package com.betterjr.modules.customer.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.betterjr.common.data.CustPasswordType;
import com.betterjr.common.data.SimpleDataEntity;
import com.betterjr.common.exception.BytterTradeException;
import com.betterjr.common.mapper.BeanMapper;
import com.betterjr.common.mq.core.RocketMQProducer;
import com.betterjr.common.mq.message.MQMessage;
import com.betterjr.common.selectkey.SerialGenerator;
import com.betterjr.common.service.BaseService;
import com.betterjr.common.utils.BTAssert;
import com.betterjr.common.utils.BetterDateUtils;
import com.betterjr.common.utils.Collections3;
import com.betterjr.common.utils.Encodes;
import com.betterjr.common.utils.IdcardUtils;
import com.betterjr.common.utils.JedisUtils;
import com.betterjr.common.utils.UserUtils;
import com.betterjr.common.utils.reflection.ReflectionUtils;
import com.betterjr.common.web.AjaxObject;
import com.betterjr.mapper.pagehelper.Page;
import com.betterjr.modules.account.dao.CustOpenAccountTmpMapper;
import com.betterjr.modules.account.data.ICustAuditEntityFace;
import com.betterjr.modules.account.entity.CustInfo;
import com.betterjr.modules.account.entity.CustOpenAccountTmp;
import com.betterjr.modules.account.entity.CustOperatorInfo;
import com.betterjr.modules.account.entity.CustOperatorRelation;
import com.betterjr.modules.account.entity.CustPassInfo;
import com.betterjr.modules.account.service.CustAccountService;
import com.betterjr.modules.account.service.CustAndOperatorRelaService;
import com.betterjr.modules.account.service.CustOperatorService;
import com.betterjr.modules.account.service.CustPassService;
import com.betterjr.modules.blacklist.service.BlacklistService;
import com.betterjr.modules.cert.entity.CustCertInfo;
import com.betterjr.modules.cert.service.CustCertService;
import com.betterjr.modules.customer.constants.CustomerConstants;
import com.betterjr.modules.customer.entity.CustBaseConfigure;
import com.betterjr.modules.customer.entity.CustInsteadApply;
import com.betterjr.modules.customer.entity.CustInsteadRecord;
import com.betterjr.modules.customer.entity.CustMechBankAccount;
import com.betterjr.modules.customer.entity.CustMechBase;
import com.betterjr.modules.customer.entity.CustMechBusinLicence;
import com.betterjr.modules.customer.entity.CustMechContacter;
import com.betterjr.modules.customer.entity.CustMechLaw;
import com.betterjr.modules.customer.entity.CustRelation;
import com.betterjr.modules.customer.entity.SysNapsBankCode;
import com.betterjr.modules.customer.helper.IFormalDataService;
import com.betterjr.modules.document.ICustFileService;
import com.betterjr.modules.document.entity.CustFileAduit;
import com.betterjr.modules.document.entity.CustFileItem;
import com.betterjr.modules.document.service.CustFileAuditService;
import com.betterjr.modules.document.service.CustFileItemService;
import com.betterjr.modules.document.utils.CustFileUtils;
import com.betterjr.modules.operator.service.OperatorRequestService;
import com.betterjr.modules.sms.constants.SmsConstants;
import com.betterjr.modules.sms.dubbo.interfaces.IVerificationCodeService;
import com.betterjr.modules.sms.entity.VerifyCode;
import com.betterjr.modules.sms.util.VerifyCodeType;
import com.betterjr.modules.sys.entity.DictInfo;
import com.betterjr.modules.sys.entity.DictItemInfo;
import com.betterjr.modules.sys.service.DictItemService;
import com.betterjr.modules.sys.service.DictService;
import com.betterjr.modules.wechat.entity.CustTempEnrollInfo;
import com.betterjr.modules.wechat.entity.CustWeChatInfo;
import com.betterjr.modules.wechat.service.CustWeChatService;
import com.betterjr.modules.wechat.service.WeChatCustEnrollService;
import com.google.common.collect.Multimap;

/**
 *
 * @author liuwl
 *
 */
@Service
public class CustOpenAccountTmpService extends BaseService<CustOpenAccountTmpMapper, CustOpenAccountTmp>
        implements IFormalDataService {

    @Autowired
    private BlacklistService blacklistService;

    @Autowired
    private CustMechLawService custMechLawService;

    @Autowired
    private CustAccountService custAccountService;

    @Autowired
    private CustMechBaseService custMechBaseService;

    @Autowired
    private CustOperatorService custOperatorService;

    @Autowired
    private CustFileItemService custFileItemService;

    @Autowired
    private CustFileAuditService custFileAuditService;

    @Autowired
    private CustInsteadRecordService custInsteadRecordService;

    @Autowired
    private CustInsteadApplyService custInsteadApplyService;

    @Autowired
    private CustAndOperatorRelaService custAndOperatorRelaService;

    @Autowired
    private CustMechBankAccountService custMechBankAccountService;

    @Autowired
    private CustMechBusinLicenceService custMechBusinLicenceService;

    @Autowired
    private CustOpenAccountAuditService custOpenAccountAuditService;

    @Autowired
    private CustRelationService custRelationService;

    @Autowired
    private DictService dictService;

    @Autowired
    private DictItemService dictItemService;

    @Resource
    private CustCertService custCertService;

    @Resource
    private RocketMQProducer betterProducer;

    @Autowired
    private CustWeChatService custWeChatService;

    @Autowired
    private WeChatCustEnrollService custEnrollService;

    @Autowired
    private CustInsteadService custInsteadService;

    @Autowired
    private CustPassService custPassService;

    @Reference(interfaceClass = IVerificationCodeService.class)
    private IVerificationCodeService verificationCodeService;

    @Reference(interfaceClass = ICustFileService.class)
    private ICustFileService custFileItemService2;

    @Autowired
    private SysNapsBankCodeService bankCodeService;

    @Autowired
    private CustBaseConfigureService custBaseConfigureService;

    @Autowired
    private CustMechContacterService custMechContacterService;

    @Autowired
    private OperatorRequestService operatorRequestService;

    /**
     * 开户资料读取
     *
     * @return
     */
    public CustOpenAccountTmp findOpenAccountInfo() {
        // 读取被驳回的记录
        final CustOpenAccountTmp anOpenAccountInfo = findRefuseAccountInfo();
        if (anOpenAccountInfo != null) {
            return anOpenAccountInfo;
        }
        // 读取暂存的记录
        return findTempStoreAccountInfo();
    }

    /**
     * 开户资料读取
     *
     * @return
     */
    public CustOpenAccountTmp findOpenAccountInfo(final Long anId) {
        BTAssert.notNull(anId, "编号不允许为空");

        // 读取被驳回的记录
        final CustOpenAccountTmp openAccountInfo = this.selectByPrimaryKey(anId);
        BTAssert.notNull(openAccountInfo, "没有找到开户信息");

        if (UserUtils.platformUser() == false && StringUtils.equals(UserUtils.getOperatorInfo().getOperOrg(),
                openAccountInfo.getOperOrg()) == false) {
            throw new BytterTradeException("接口调用错误");
        }

        return openAccountInfo;
    }

    private CustOpenAccountTmp findTempStoreAccountInfo() {
        final Map<String, Object> anMap = new HashMap<String, Object>();
        anMap.put("operOrg", UserUtils.getOperatorInfo().getOperOrg());
        anMap.put("businStatus", CustomerConstants.TMP_STATUS_NEW);
        anMap.put("tmpType", CustomerConstants.TMP_TYPE_TEMPSTORE);
        return Collections3.getFirst(this.selectByProperty(anMap));
    }

    private CustOpenAccountTmp findRefuseAccountInfo() {
        final Map<String, Object> anMap = new HashMap<String, Object>();
        anMap.put("operOrg", UserUtils.getOperatorInfo().getOperOrg());
        anMap.put("businStatus", CustomerConstants.TMP_STATUS_REFUSE);
        anMap.put("tmpType", CustomerConstants.TMP_TYPE_TEMPSTORE);
        return Collections3.getFirst(this.selectByProperty(anMap));
    }

    /**
     * 开户资料暂存
     */
    public CustOpenAccountTmp saveOpenAccountInfo(final CustOpenAccountTmp anOpenAccountInfo, final Long anId,
            final String anFileList) {
        logger.info("Begin to Save Open Account Infomation");
        if (StringUtils.isBlank(anOpenAccountInfo.getWechatOpenId())) {
            // 检查开户资料合法性(pc)
            checkAccountInfoValid(anOpenAccountInfo);
        } else {
            // 检查开户资料合法性,部分检查(微信)
            wechatCheckAccountInfoValid(anOpenAccountInfo);
        }
        if (null == anId) {
            // 初始化参数设置
            initAddValue(anOpenAccountInfo, CustomerConstants.TMP_TYPE_TEMPSTORE, CustomerConstants.TMP_STATUS_NEW);
            // 初始化微信相应选--解决前端默认值被暂存刷新问题
            anOpenAccountInfo.initDefaultValue();
            // 处理附件
            anOpenAccountInfo
                    .setBatchNo(custFileItemService.updateCustFileItemInfo(anFileList, anOpenAccountInfo.getBatchNo()));
            // 数据存盘,开户资料暂存
            this.insert(anOpenAccountInfo);
        } else {
            final CustOpenAccountTmp anExitsOpenAccountInfo = this.selectByPrimaryKey(anId);
            BTAssert.notNull(anExitsOpenAccountInfo, "无法获取客户开户资料信息");
            // 初始化参数设置
            anOpenAccountInfo.initModifyValue(anExitsOpenAccountInfo);
            // 营业执照
            initIdentInfo(anOpenAccountInfo);
            // 处理附件
            anOpenAccountInfo
                    .setBatchNo(custFileItemService.updateCustFileItemInfo(anFileList, anOpenAccountInfo.getBatchNo()));
            // 数据存盘,开户资料暂存
            this.updateByPrimaryKeySelective(anOpenAccountInfo);
        }
        return anOpenAccountInfo;
    }

    /**
     * 开户申请
     *
     * @param anOpenAccountInfo
     * @param anId
     * @return
     */
    public CustOpenAccountTmp saveOpenAccountApply(final CustOpenAccountTmp anOpenAccountInfo, final Long anId,
            final String anFileList) {
        logger.info("Begin to Commit Open Account Apply");
        // 检查开户资料合法性
        checkAccountInfoValid(anOpenAccountInfo);
        // 开户流水号
        if (null == anId) {
            // 初始化参数设置
            initAddValue(anOpenAccountInfo, CustomerConstants.TMP_TYPE_TEMPSTORE, CustomerConstants.TMP_STATUS_OWN);
            // 处理附件
            anOpenAccountInfo
                    .setBatchNo(custFileItemService.updateCustFileItemInfo(anFileList, anOpenAccountInfo.getBatchNo()));
            // 数据存盘,开户资料暂存
            this.insert(anOpenAccountInfo);
        } else {
            // 加载已暂存的开户资料
            final CustOpenAccountTmp anExitsOpenAccountInfo = this.selectByPrimaryKey(anId);
            BTAssert.notNull(anExitsOpenAccountInfo, "无法获取客户开户资料信息");
            // 初始化参数设置
            anOpenAccountInfo.initModifyValue(anExitsOpenAccountInfo);
            // 营业执照
            initIdentInfo(anOpenAccountInfo);
            // 设置状态为使用中
            anOpenAccountInfo.setBusinStatus(CustomerConstants.TMP_STATUS_OWN);
            anOpenAccountInfo.setLastStatus(CustomerConstants.TMP_STATUS_OWN);
            // 申请日期
            anOpenAccountInfo.setApplyDate(BetterDateUtils.getNumDate());
            // 申请时间
            anOpenAccountInfo.setApplyTime(BetterDateUtils.getNumTime());
            // 处理附件
            anOpenAccountInfo
                    .setBatchNo(custFileItemService.updateCustFileItemInfo(anFileList, anOpenAccountInfo.getBatchNo()));
            // 数据存盘,开户资料暂存
            this.updateByPrimaryKeySelective(anOpenAccountInfo);
        }
        // 写入开户日志
        custOpenAccountAuditService.addInitOpenAccountApplyLog(anOpenAccountInfo.getId(), "自动通过", "开户申请");

        return anOpenAccountInfo;
    }

    /**
     * 开户申请待审批列表
     *
     * @param anFlag
     * @param anPageNum
     * @param anPageSize
     * @return
     */
    public Page<CustOpenAccountTmp> queryOpenAccountApply(final String anFlag, final int anPageNum,
            final int anPageSize) {
        final Map<String, Object> anMap = new HashMap<String, Object>();
        anMap.put("businStatus", CustomerConstants.TMP_STATUS_OWN);// 状态:自主开户

        return this.selectPropertyByPage(CustOpenAccountTmp.class, anMap, anPageNum, anPageSize, "1".equals(anFlag));
    }

    /**
     * 微信开户审核生效
     *
     * @param anId
     * @return
     */
    public CustOpenAccountTmp addWeChatAccount(final Long anId) {
        // 获取客户开户资料
        final CustOpenAccountTmp anOpenAccountInfo = this.selectByPrimaryKey(anId);
        BTAssert.notNull(anOpenAccountInfo, "无法获取客户开户资料信息");
        // 检查开户资料合法性
        checkAccountInfoValid(anOpenAccountInfo);
        if (StringUtils.equals(anOpenAccountInfo.getBusinStatus(), CustomerConstants.TMP_STATUS_USEING)) {
            // 生成开户数据
            createWeChatValidAccount(anOpenAccountInfo, anOpenAccountInfo.getRegOperId(),
                    anOpenAccountInfo.getRegOperName(), anOpenAccountInfo.getOperOrg());
            // 设置状态为已使用
            anOpenAccountInfo.setBusinStatus(CustomerConstants.TMP_STATUS_USED);
            anOpenAccountInfo.setLastStatus(CustomerConstants.TMP_STATUS_USED);
            // 审核日期
            anOpenAccountInfo.setAuditDate(BetterDateUtils.getNumDate());
            // 审核时间
            anOpenAccountInfo.setAuditTime(BetterDateUtils.getNumTime());
            // 更新数据
            this.updateByPrimaryKeySelective(anOpenAccountInfo);
        }

        return anOpenAccountInfo;
    }

    /**
     * 开户审核生效
     *
     * @param anId
     * @param anAuditOpinion
     * @return
     */
    public CustOpenAccountTmp saveAuditOpenAccountApply(final Long anId, final String anAuditOpinion) {
        // 检查操作员是否能执行审核操作
        checkPlatformUser();
        // 获取客户开户资料
        final CustOpenAccountTmp anOpenAccountInfo = this.selectByPrimaryKey(anId);
        BTAssert.notNull(anOpenAccountInfo, "无法获取客户开户资料信息");
        // 检查开户资料合法性
        checkAccountInfoValid(anOpenAccountInfo);
        if (StringUtils.equals(anOpenAccountInfo.getBusinStatus(), CustomerConstants.TMP_STATUS_OWN)) {
            // 生成开户数据
            createValidAccount(anOpenAccountInfo, anOpenAccountInfo.getRegOperId(), anOpenAccountInfo.getRegOperName(),
                    anOpenAccountInfo.getOperOrg());
            // 设置状态为已使用
            anOpenAccountInfo.setBusinStatus(CustomerConstants.TMP_STATUS_USED);
            anOpenAccountInfo.setLastStatus(CustomerConstants.TMP_STATUS_USED);
            // 审核日期
            anOpenAccountInfo.setAuditDate(BetterDateUtils.getNumDate());
            // 审核时间
            anOpenAccountInfo.setAuditTime(BetterDateUtils.getNumTime());
            // 更新数据
            this.updateByPrimaryKeySelective(anOpenAccountInfo);
            // 写入开户日志
            custOpenAccountAuditService.addAuditOpenAccountApplyLog(anOpenAccountInfo.getId(), anAuditOpinion, "开户审核");

            // 发消息
            final MQMessage anMessage = new MQMessage("CUSTOMER_OPENACCOUNT_TOPIC");
            try {
                anMessage.setObject(anOpenAccountInfo);
                anMessage.addHead("type", "1");// 开户成功
                anMessage.addHead("operator", UserUtils.getOperatorInfo());
                betterProducer.sendMessage(anMessage);
            }
            catch (final Exception e) {
                logger.error("异步消息发送失败！", e);
            }
        }
        return anOpenAccountInfo;
    }

    /**
     * 客户确认开户激活
     */
    @Override
    public void saveFormalData(final Long anParentId) {
        BTAssert.notNull(anParentId, "代录记录流水号不允许为空！");
        // 获取客户开户资料信息
        final CustOpenAccountTmp anOpenAccountInfo = Collections3
                .getFirst(this.selectByProperty("parentId", anParentId));
        BTAssert.notNull(anOpenAccountInfo, "无法获取客户开户资料信息");
        // 检查开户资料合法性
        checkAccountInfoValid(anOpenAccountInfo);
        if (StringUtils.equals(anOpenAccountInfo.getBusinStatus(), CustomerConstants.TMP_STATUS_USEING)) {
            // 生成开户数据，区分微信和PC
            if (!StringUtils.isEmpty(anOpenAccountInfo.getWechatOpenId())) {
                createValidAccount(anOpenAccountInfo, anOpenAccountInfo.getRegOperId(),
                        anOpenAccountInfo.getRegOperName(), anOpenAccountInfo.getOperOrg());
            } else {
                createValidAccount(anOpenAccountInfo, UserUtils.getOperatorInfo().getId(),
                        UserUtils.getOperatorInfo().getName(), UserUtils.getOperatorInfo().getOperOrg());
            }
            // 更新数据,变更状态
            anOpenAccountInfo.setLastStatus(anOpenAccountInfo.getBusinStatus());
            anOpenAccountInfo.setBusinStatus(CustomerConstants.TMP_STATUS_USED);
            // 激活日期
            anOpenAccountInfo.setActiveDate(BetterDateUtils.getNumDate());
            anOpenAccountInfo.setActiveTime(BetterDateUtils.getNumTime());
            this.updateByPrimaryKeySelective(anOpenAccountInfo);

            // 回写暂存流水号至代录申请表
            final CustInsteadRecord insteadRecord = custInsteadRecordService.findInsteadRecord(anParentId);

            custInsteadApplyService.saveCustInsteadApplyCustInfo(insteadRecord.getApplyId(),
                    anOpenAccountInfo.getCustNo(), anOpenAccountInfo.getCustName());
        }
    }

    /**
     * 开户申请驳回
     *
     * @param anId
     * @param anAuditOpinion
     * @return
     */
    public CustOpenAccountTmp saveRefuseOpenAccountApply(final Long anId, final String anAuditOpinion) {
        // 检查操作员是否能执行审核操作
        checkPlatformUser();
        // 获取客户开户资料
        final CustOpenAccountTmp anOpenAccountInfo = this.selectByPrimaryKey(anId);
        BTAssert.notNull(anOpenAccountInfo, "无法获取客户开户资料信息");
        // 设置状态为驳回
        anOpenAccountInfo.setBusinStatus(CustomerConstants.TMP_STATUS_REFUSE);
        anOpenAccountInfo.setLastStatus(CustomerConstants.TMP_STATUS_REFUSE);
        // 审核日期
        anOpenAccountInfo.setAuditDate(BetterDateUtils.getNumDate());
        // 审核时间
        anOpenAccountInfo.setAuditTime(BetterDateUtils.getNumTime());
        // 更新数据
        this.updateByPrimaryKeySelective(anOpenAccountInfo);
        // 写入开户日志
        custOpenAccountAuditService.addRefuseOpenAccountApplyLog(anOpenAccountInfo.getId(), anAuditOpinion, "开户审核");

        // 发消息
        final MQMessage anMessage = new MQMessage("CUSTOMER_OPENACCOUNT_TOPIC");

        try {
            anMessage.setObject(anOpenAccountInfo);
            anMessage.addHead("type", "0"); // 驳回
            anMessage.addHead("operator", UserUtils.getOperatorInfo());
            anMessage.addHead("auditOpinion", anAuditOpinion);
            betterProducer.sendMessage(anMessage);
        }
        catch (final Exception e) {
            logger.error("异步消息发送失败！", e);
        }
        return anOpenAccountInfo;
    }

    /**
     * PC代录开户资料提交
     */
    public CustOpenAccountTmp saveOpenAccountInfoByInstead(final CustOpenAccountTmp anOpenAccountInfo,
            final Long anInsteadRecordId, final String anFileList) {
        logger.info("Begin to Save Open Account Infomation Instead");
        // 代录流水号不能为空
        BTAssert.notNull(anInsteadRecordId, "代录流水号不能为空");
        // 检查开户资料合法性
        checkAccountInfoValid(anOpenAccountInfo);
        // 检查是否已存在代录
        final CustInsteadRecord anInsteadRecord = custInsteadRecordService.selectByPrimaryKey(anInsteadRecordId);
        BTAssert.notNull(anInsteadRecord, "无法获取代录信息");
        // 获取代录暂存的开户资料ID号
        final String anTempId = anInsteadRecord.getTmpIds();

        // 检查联行号不存在而银行全称正确情况，则可通过银行全称再获取一遍联行号
        if (StringUtils.isBlank(anOpenAccountInfo.getPaySysNum())) {
            final SysNapsBankCode bankCode = bankCodeService
                    .findSysBankCodeInfoByBankName(anOpenAccountInfo.getBankName());
            if (bankCode == null) {
                throw new BytterTradeException("银行全称输入不正确，请检查");
            } else {
                anOpenAccountInfo.setPaySysNum(bankCode.getPaySysNum());
            }
        }

        // 检查联行号对应的银行名称与所输入的银行全称是否一致
        bankCodeService.checkBankCode(anOpenAccountInfo.getPaySysNum(), anOpenAccountInfo.getBankName());

        if (null == anTempId) {
            // 初始化参数设置
            initAddValue(anOpenAccountInfo, CustomerConstants.TMP_TYPE_INSTEADSTORE,
                    CustomerConstants.TMP_STATUS_USEING);
            // 处理附件
            anOpenAccountInfo
                    .setBatchNo(custFileItemService.updateCustFileItemInfo(anFileList, anOpenAccountInfo.getBatchNo()));
            // 数据存盘,开户资料暂存
            this.insert(anOpenAccountInfo);
        } else {
            // 加载已暂存的开户资料
            final CustOpenAccountTmp anExitsOpenAccountInfo = this.selectByPrimaryKey(Long.valueOf(anTempId));
            // 初始化参数设置
            anOpenAccountInfo.initModifyValue(anExitsOpenAccountInfo);
            // 营业执照
            initIdentInfo(anOpenAccountInfo);
            // 设置状态为使用
            anOpenAccountInfo.setBusinStatus(CustomerConstants.TMP_STATUS_USEING);
            anOpenAccountInfo.setLastStatus(CustomerConstants.TMP_STATUS_USEING);
            // 处理附件
            anOpenAccountInfo
                    .setBatchNo(custFileItemService.updateCustFileItemInfo(anFileList, anOpenAccountInfo.getBatchNo()));
            // 数据存盘,开户资料暂存
            this.updateByPrimaryKeySelective(anOpenAccountInfo);
        }
        // 回写暂存流水号至代录申请表
        final CustInsteadRecord insteadRecord = custInsteadRecordService.saveInsteadRecord(anInsteadRecordId,
                String.valueOf(anOpenAccountInfo.getId()));

        // 回写 parentId by instead record id. add by Liuwl 2016-10-12
        anOpenAccountInfo.setParentId(insteadRecord.getId());
        this.updateByPrimaryKeySelective(anOpenAccountInfo);

        custInsteadApplyService.saveCustInsteadApplyCustInfo(insteadRecord.getApplyId(), null,
                anOpenAccountInfo.getCustName());

        return anOpenAccountInfo;
    }

    /**
     * 
     * @Title: saveOpenAccountInfoByInstead
     * @Description: TODO(代开户信息)
     * @param @param
     *            anOpenAccountInfo
     * @param @param
     *            anInsteadRecordId
     * @param @param
     *            anFileList
     * @param @return
     *            参数说明
     * @return CustOpenAccountTmp 返回类型
     * @throws @author
     *             chenlq
     * @date 2018年6月27日 下午2:03:33
     */
    public CustOpenAccountTmp saveInsteadOpenAccountInfo(final Map<String, Object> anMap, final Long opeatorId,
            final String custType, final String anFileList) {
        logger.info("Begin to Save Open Account Infomation Instead");
        // 检查参数不能为空！
        checkDataValidate(anMap);
        final CustOpenAccountTmp anOpenAccountInfo = associateOpenInfo(anMap);

        // 检查开户资料合法性
        try {
            checkAccountInfoValidAfter(anOpenAccountInfo);
        }
        catch (final Exception e) {
            // 抛出错误检查信息
            BTAssert.notNull(null, e.getMessage());
        }

        // 检查联行号不存在而银行全称正确情况，则可通过银行全称再获取一遍联行号
        if (StringUtils.isBlank(anOpenAccountInfo.getPaySysNum())) {
            final SysNapsBankCode bankCode = bankCodeService
                    .findSysBankCodeInfoByBankName(anOpenAccountInfo.getBankName());
            if (bankCode == null) {
                BTAssert.notNull(null, "银行全称输入不正确，你输入的银行不存在，请核准你的银行全称是否能在银行联行号中找到！");
            } else {
                anOpenAccountInfo.setPaySysNum(bankCode.getPaySysNum());
            }
        }

        // 检查联行号对应的银行名称与所输入的银行全称是否一致
        bankCodeService.checkBankCode(anOpenAccountInfo.getPaySysNum(), anOpenAccountInfo.getBankName());

        // 初始化参数设置
        initAddValue(anOpenAccountInfo, CustomerConstants.TMP_TYPE_INSTEADSTORE, CustomerConstants.TMP_STATUS_USEING);
        if (anFileList != null) {
            // 处理附件
            anOpenAccountInfo
                    .setBatchNo(custFileItemService.updateCustFileItemInfo(anFileList, anOpenAccountInfo.getBatchNo()));
        }
        // 数据存盘,开户资料暂存
        this.insert(anOpenAccountInfo);
        // 企业信息绑定平台创建的客户
        final CustOperatorInfo operatorInfo = this.operatorRequestService.selectByPrimaryKey(opeatorId);
        if (operatorInfo == null) {
            BTAssert.notNull(null, "该开户操作员不存在，请确该操作员创建成功！");
        }
        // 保存联系人信息
        // this.custMechContacterService.addCustMechContacter(anOpenAccountInfo);
        createWeChatValidAccountAfter(anOpenAccountInfo, opeatorId, operatorInfo.getName(),
                anOpenAccountInfo.getCustName(), operatorInfo);
        return anOpenAccountInfo;
    }

    /**
     * 
     * @Title: checkDataValidate 
     * @Description: TODO(检查传过来的值不能为空) 
     * @param @param map 参数说明 
     * @return void 返回类型 
     * @throws 
     * @author chenlq
     * @date 2018年7月14日 下午4:31:10
     */
    public void checkDataValidate(Map<String, Object> map) {
        // 申请机构名称
        final String custName = map.get("custName").toString();
        if (custName == null || custName.equals("")) {
            BTAssert.notNull(null, "申请机构名称不能为空！");
        }
        // 营业执照号码
        final String businLicence = map.get("businLicence").toString();
        if (businLicence == null || businLicence.equals("")) {
            BTAssert.notNull(null, "营业执照号不能为空！！");
        }
        // 组织机构代码
        final String orgCode = map.get("orgCode").toString();
        if (orgCode == null || orgCode.equals("")) {
            BTAssert.notNull(null, "组织机构代码不能为空！");
        }
        // 营业执照有效期
        final String businLicenceValidDate = map.get("businLicenceValidDate").toString();
        if (businLicenceValidDate == null || businLicenceValidDate.equals("")) {
            BTAssert.notNull(null, "营业执照有效期不能为空！");
        }
        // 税务登记号码
        final String taxNo = map.get("taxNo").toString();
        if (taxNo == null || taxNo.equals("")) {
            BTAssert.notNull(null, "税务登记证号不能为空！");
        }
        // 联系电话
        final String phone = map.get("phone").toString();
        if (phone == null || phone.equals("")) {
            BTAssert.notNull(null, "业务联系电话不能为空！");
        }
        // 校验电话格式是否正确
        final String regex = "(?:(\\(\\+?86\\))(0[0-9]{2,3}\\-?)?([2-9][0-9]{6,7})+(\\-[0-9]{1,4})?)|"
                + "(?:(86-?)?(0[0-9]{2,3}\\-?)?([2-9][0-9]{6,7})+(\\-[0-9]{1,4})?)";
        if (!Pattern.matches(regex, phone) || phone.length() > 20) {
            BTAssert.notNull(null, "业务联系电话输入格式不正确，请输入正确的电话号码，例如：xxxx-xxxxxxx！");
        }
        // 传真
        final String fax = map.get("fax").toString();
        if (fax == null || fax.equals("")) {
            BTAssert.notNull(null, "传真号不能为空！！");
        }
        // 检查传真号格式的正确性
        if (!Pattern.matches(regex, fax) || fax.length() > 20) {
            BTAssert.notNull(null, "传真号格式不正确，请输入正确的传真格式,例如：xxxx-xxxxxxx！！");
        }
        // 邮政编码
        final String zipCode = map.get("zipCode").toString();
        if (zipCode == null || zipCode.equals("")) {
            BTAssert.notNull(null, "邮政编号不能为空！");
        }
        // 校验邮政编码格式的正确性
        final String zipCoderegex = "^[0-9]\\d{5}$";
        if (!Pattern.matches(zipCoderegex, zipCode)) {
            BTAssert.notNull(null, "邮政编号格式不正确，请检查输入的邮政编码是否符合要求！");
        }
        // 办工地址
        final String address = map.get("address").toString();
        if (address == null || address.equals("")) {
            BTAssert.notNull(null, "办公地址不能为空！");
        }
        // 客户类型
        final String custType = map.get("custType").toString();
        if (custType == null || custType.equals("")) {
            BTAssert.notNull(null, "客户类型不能为空！");
        }

        // 校验银行信息
        // 银行账户名
        final String bankAccoName = map.get("bankAccoName").toString();
        if (bankAccoName == null || bankAccoName.equals("")) {
            BTAssert.notNull(null, "银行账户名称不能为空！");
        }
        if (bankAccoName.length() > 120) {
            BTAssert.notNull(null, "银行账户不能超过120位！");
        }

        // 银行卡账户验证
        final String bankAcco = map.get("bankAcco").toString();
        if (bankAcco == null || bankAcco.equals("")) {
            BTAssert.notNull(null, "银行账户名称不能为空！");
        }
        final String bankAccoRegex = "\\d+";
        if (!Pattern.matches(bankAccoRegex, bankAcco) || bankAccoRegex.length() > 32) {
            BTAssert.notNull(null, "银行账号格式不正确，请检查输入的银行卡号是否全为数字且不能超过32位！");
        }

        // 开户许可证号验证
        final String openLicense = map.get("openLicense").toString();
        if (openLicense == null || openLicense.equals("")) {
            BTAssert.notNull(null, "银行开户许可证号不能为空！");
        }

        // 验证所属银行
        final String bankNo = map.get("bankNo").toString();
        if (bankNo == null || bankNo.equals("")) {
            BTAssert.notNull(null, "所属银行不能为空！");
        }

        // 开户行全称验证
        final String bankName = map.get("bankName").toString();
        if (bankName == null || bankName.equals("")) {
            BTAssert.notNull(null, "开户银行全称不能为空！");
        }

        // 银行开户所在地验证
        final String provinceNo = map.get("provinceNo").toString();
        if (provinceNo == null || bankName.equals("")) {
            BTAssert.notNull(null, "开户所在地编号不能为空！");
        }

        // 法人代表名验证
        final String lawName = map.get("lawName").toString();
        if (lawName == null || lawName.equals("")) {
            BTAssert.notNull(null, "法人信息不能为空！");
        }

        // 证件类型验证
        final String lawIdentType = map.get("lawIdentType").toString();
        if (lawIdentType == null || lawIdentType.equals("")) {
            BTAssert.notNull(null, "证件类型不能为空！");
        }

        // 法人证件类型验证
        final String lawIdentNo = map.get("lawIdentNo").toString();
        if (lawIdentNo == null || lawIdentNo.equals("")) {
            BTAssert.notNull(null, "法人身份证号码不能为空！");
        }
        // 验证格式
        final String lawIdentNoregex = "^(\\d{6})(19|20)(\\d{2})(1[0-2]|0[1-9])(0[1-9]|[1-2][0-9]|3[0-1])(\\d{3})(\\d|X|x)?$";
        if (!Pattern.matches(lawIdentNoregex, lawIdentNo)) {
            BTAssert.notNull(null, "法人身份证格式不正确，请输入正确的身份证号码！");
        }

        // 法人证件有效期校验
        final String lawValidDate = map.get("lawValidDate").toString();
        if (lawValidDate == null || lawValidDate.equals("")) {
            BTAssert.notNull(null, "证件有效期不能为空！");
        }

    }

    /**
     * 关联开户信息
     * 
     * @param map
     * @return
     */
    public CustOpenAccountTmp associateOpenInfo(final Map<String, Object> map) {

        final CustOpenAccountTmp anOpen = new CustOpenAccountTmp();
        /*
         * 开户基本资料录入
         */
        // 申请机构名称
        anOpen.setCustName(map.get("custName").toString());
        // 组织机构代码
        anOpen.setOrgCode(map.get("orgCode").toString());
        // 税务登记证号码
        anOpen.setTaxNo(map.get("taxNo").toString());
        // 营业执照号码
        anOpen.setBusinLicence(map.get("businLicence").toString());
        // 营业执照有效期
        anOpen.setBusinLicenceValidDate(map.get("businLicenceValidDate").toString());
        // 业务联系电话
        anOpen.setPhone(map.get("phone").toString());
        // 传真
        anOpen.setFax(map.get("fax").toString());
        // 邮政编码
        anOpen.setZipCode(map.get("zipCode").toString());
        // 办公地址
        anOpen.setAddress(map.get("address").toString());
        // 客户类型
        anOpen.setCustType(map.get("custType").toString());

        /*
         * 开户银行账户信息录入
         */
        // 银行账户名称
        anOpen.setBankAccoName(map.get("bankAccoName").toString());
        // 银行账号
        anOpen.setBankAcco(map.get("bankAcco").toString());
        // 开户许可证核准号
        anOpen.setOpenLicense(map.get("openLicense").toString());
        // 所属银行
        anOpen.setBankNo(map.get("bankNo").toString());
        // 开户行全称
        anOpen.setBankName(map.get("bankName").toString());
        // 开户行所在省市
        anOpen.setProvinceNo(map.get("provinceNo").toString());
        // 开户行所在市
        anOpen.setBankCityno(map.get("provinceNo").toString());
        if (map.get("countyName").toString() != null && !map.get("countyName").toString().equals("")
                && map.get("cityName").toString() != null && !map.get("cityName").toString().equals("")) {
            // 开户行所在省名称
            anOpen.setProvinceName(map.get("countyName").toString());
            // 开户行所在市名称
            anOpen.setCityName(map.get("cityName").toString());
        }
        final String bankPropertyName = map.get("bankPropertyName").toString();
        if (bankPropertyName != null && !bankPropertyName.equals("")) {
            anOpen.setBankPropertyName(bankPropertyName);
        }

        /*
         * 法人代表/负责人信息录入
         */
        // 姓名
        anOpen.setLawName(map.get("lawName").toString());
        // 证件类型
        anOpen.setLawIdentType(map.get("lawIdentType").toString());
        // 证件号码
        anOpen.setLawIdentNo(map.get("lawIdentNo").toString());
        // 证件有效期
        anOpen.setLawValidDate(map.get("lawValidDate").toString());
        return anOpen;
    }

    /**
     * 
     * @Title: saveCustBaseConfigure
     * @Description: TODO(保存客户基础配置)
     * @param @return
     *            参数说明
     * @return CustBaseConfigure 返回类型
     * @throws @author
     *             chenlq
     * @date 2018年6月27日 下午9:18:47
     */
    public CustBaseConfigure saveCustBaseConfigure(final Map<String, Object> anMap, final Long custNo,
            final String custName) {
        // 判断系统标识
        final String systemIdentifition = anMap.get("systemIdentifition").toString();
        if (systemIdentifition == null || systemIdentifition.equals("")) {
            BTAssert.notNull(null, "系统标识不能为空");
        }
        // 判断客户标识
        final String custIdentifition = anMap.get("custIdentifition").toString();
        if (custIdentifition == null || custIdentifition.equals("")) {
            BTAssert.notNull(null, "客户标识不能为空！");
        }
        // 系统服务地址
        final String servicerUrl = anMap.get("servicerUrl").toString();
        if (servicerUrl == null || servicerUrl.equals("")) {
            BTAssert.notNull(null, "系统服务器地址不能为空！");
        }

        if (anMap.get("servicerType").toString().equals("2")) {
            final String couldIdtifition = anMap.get("couldIdtifition").toString();
            if (couldIdtifition == null || couldIdtifition.equals("")) {
                BTAssert.notNull(null, "云平台客户标识不能为空！");
            }
        }

        // 系统服务器类型
        final String servicerType = anMap.get("servicerType").toString();
        if (servicerType == null || servicerType.equals("")) {
            BTAssert.notNull(null, "服务器类型不能为空！");
        }

        // 加密方式
        final String encryptMay = anMap.get("encryptMay").toString();
        if (encryptMay == null || encryptMay.equals("")) {
            BTAssert.notNull(null, "通讯加密方式不能为空！");
        }
        BTAssert.notNull(custNo, "客户编号不能为空");
        BTAssert.notNull(custName, "客户名称不能为空！");
        final CustBaseConfigure custBase = new CustBaseConfigure();

        custBase.initValue();
        custBase.setSystemIdentifition(anMap.get("systemIdentifition").toString());
        custBase.setEncryptMay(anMap.get("encryptMay").toString());
        custBase.setCustIdentifition(anMap.get("custIdentifition").toString());
        custBase.setServicerUrl(anMap.get("servicerUrl").toString());
        custBase.setServicerType(anMap.get("servicerType").toString());

        if (anMap.get("servicerType").toString().equals("2")) {
            // 判断有没有云标识
            final String cloudId = anMap.get("couldIdtifition").toString();
            if (cloudId != null && !cloudId.equals("")) {
                custBase.setCouldIdtifition(cloudId);
            }
        }

        custBase.setCustNo(custNo);
        custBase.setCustName(custName);

        final Long configId = checkConfigureExist(anMap, custNo);//
        // 检查是否存在
        if (null != configId) {
            this.custBaseConfigureService.updateByExampleSelective(custBase, "id", configId);
        } else {
            this.custBaseConfigureService.insert(custBase);
        }
        return custBase;
    }

    /**
     * 
     * @Title: custBaseConfigureQuery
     * @Description: TODO(客户基础配置查询)
     * @param @param
     *            custNo
     * @param @param
     *            serviceType
     * @param @return
     *            参数说明
     * @return List<CustBaseConfigure> 返回类型
     * @throws @author
     *             chenlq
     * @date 2018年7月2日 下午8:11:42
     */
    public List<CustBaseConfigure> custBaseConfigureQuery(final Long custNo, final String serviceType) {
        BTAssert.notNull(custNo, "客户编号为空,查询失败！");
        final CustBaseConfigure custBase = new CustBaseConfigure();
        custBase.setCustNo(custNo);
        List<CustBaseConfigure> custBaseList = new ArrayList<CustBaseConfigure>();
        if (serviceType == null || serviceType.equals("")) {
            custBaseList = this.custBaseConfigureService.select(custBase);
        } else {
            custBase.setServicerType(serviceType);
            custBaseList = this.custBaseConfigureService.select(custBase);
        }

        return custBaseList;
    }

    /**
     * 
     * @Title: custBaseConfigureQuery 
     * @Description: TODO(判断系统属性) 
     * @param @param custNo
     * @param @param serviceType
     * @param @return 参数说明 
     * @return Map<String,CustBaseConfigure> 返回类型 
     * @throws 
     * @author chenlq
     * @date 2018年7月9日 下午8:12:01
     */
    public Map<String, CustBaseConfigure> baseConfigureQuery(final Long custNo, final String serviceType) {
        BTAssert.notNull(custNo, "客户编号为空,查询失败！");
        final CustBaseConfigure custBase = new CustBaseConfigure();
        custBase.setCustNo(custNo);
        List<CustBaseConfigure> custBaseList = new ArrayList<CustBaseConfigure>();
        if (serviceType == null || serviceType.equals("")) {
            custBaseList = this.custBaseConfigureService.select(custBase);
        } else {
            custBase.setServicerType(serviceType);
            custBaseList = this.custBaseConfigureService.select(custBase);
        }
        if (custBaseList.size() == 0) {
            BTAssert.notNull(null, "该客户还没有任何配置信息，如需要添加配置信息，请在下面操作！");
        }
        final Map<String, CustBaseConfigure> result = new HashMap<String, CustBaseConfigure>();
        if (custBaseList.get(0).getServicerType().equals("1")) {
            result.put("frontConfig", custBaseList.get(0));
        }
        if (custBaseList.get(0).getServicerType().equals("2")) {
            result.put("afterConfig", custBaseList.get(0));
        }
        if (custBaseList.size() == 2) {
            if (custBaseList.get(1).getServicerType().equals("1")) {
                result.put("frontConfig", custBaseList.get(1));
            }
            if (custBaseList.get(1).getServicerType().equals("2")) {
                result.put("afterConfig", custBaseList.get(1));
            }
        }
        return result;
    }

    /**
     * 
     * @Title: checkConfigureExist
     * @Description: TODO(检查是否配置了系统)
     * @param @param
     *            anMap
     * @param @param
     *            custNo
     * @param @param
     *            custName 参数说明
     * @return void 返回类型
     * @throws @author
     *             chenlq
     * @date 2018年7月2日 下午7:31:37
     */
    public Long checkConfigureExist(final Map<String, Object> anMap, final Long custNo) {
        final CustBaseConfigure baseConfig = new CustBaseConfigure();
        baseConfig.setCustNo(custNo);
        baseConfig.setServicerType(anMap.get("servicerType").toString());
        final CustBaseConfigure config = this.custBaseConfigureService.selectOne(baseConfig);
        if (null != config) {
            return config.getId();
        }
        return null;
    }

    /**
     * 
     * @Title: createCustSign
     * @Description: TODO(生成标识符)
     * @param @param
     *            idSign
     * @param @param
     *            idType
     * @param @return
     *            参数说明
     * @return String 返回类型
     * @throws @author
     *             chenlq
     * @date 2018年6月28日 下午3:40:31
     */
    public String createCustSign(final String idSign, final Long idType) {
        BTAssert.notNull(idSign, "标识不能为空！");
        BTAssert.notNull(idType, "类型不能为空！");
        String hash = "";
        if (idType == 1) {// idtype = 1为系统标识
            if (idSign == null || idSign.equals("")) {
                BTAssert.notNull(null, "系统标识内容输入框不能为空！");
            }
            hash = Encodes.getMD5(idSign).substring(8, 24);
        } else if (idType == 2) {// 客户标识
            if (idSign == null || idSign.equals("")) {
                BTAssert.notNull(null, "客户标识内容输入框不能为空！");
            }
            hash = Encodes.getMD5(idSign);
        } else {
            BTAssert.notNull(null, "标识符生成失败！");
        }
        return hash;
    }

    /**
     * 代录开户资料读取
     *
     * @param anInsteadId
     * @return
     */
    public CustOpenAccountTmp findOpenAccountInfoByInsteadId(final Long anInsteadId) {
        // 检查是否已存在代录
        final CustInsteadRecord anInsteadRecord = custInsteadRecordService.selectByPrimaryKey(anInsteadId);
        BTAssert.notNull(anInsteadRecord, "无法获取代录信息");
        // 获取代录暂存的开户资料ID号
        final String anTempId = anInsteadRecord.getTmpIds();
        BTAssert.notNull(anTempId, "无法获取客户开户资料信息");

        return this.selectByPrimaryKey(Long.valueOf(anTempId));
    }

    @Override
    public void saveCancelData(final Long anParentId) {
        // TODO Auto-generated method stub

    }

    private void checkPlatformUser() {
        if (UserUtils.platformUser() == false) {
            logger.warn("当前操作员不能执行该操作");
            throw new BytterTradeException(40001, "当前操作员不能执行该操作");
        }
    }

    private void initAddValue(final CustOpenAccountTmp anOpenAccountInfo, final String anTmpType,
            final String anBusinStatus) {
        anOpenAccountInfo.initAddValue();
        // 设置类型:自己暂存/平台操作员代录时暂存
        anOpenAccountInfo.setTmpType(anTmpType);
        // 设置状态为使用中
        anOpenAccountInfo.setBusinStatus(anBusinStatus);
        anOpenAccountInfo.setLastStatus(anBusinStatus);
        // 营业执照
        initIdentInfo(anOpenAccountInfo);
    }

    private void initIdentInfo(final CustOpenAccountTmp anOpenAccountInfo) {
        anOpenAccountInfo.setIdentNo(anOpenAccountInfo.getBusinLicence());
        anOpenAccountInfo.setIdentType("1");
        anOpenAccountInfo.setValidDate(anOpenAccountInfo.getBusinLicenceValidDate());
    }

    private void createWeChatValidAccount(final CustOpenAccountTmp anOpenAccountInfo, final Long anOperId,
            final String anOperName, final String anOperOrg) {
        // 开户资料附件
        final Long anBatchNo = anOpenAccountInfo.getBatchNo();

        // 开户资料附件信息
        final Multimap<String, Object> anCustFileItem = ReflectionUtils
                .listConvertToMuiltMap(custFileItemService.findCustFiles(anBatchNo), "fileInfoType");

        // 数据存盘,客户资料
        final CustInfo custInfo = addCustInfo(anOpenAccountInfo, anOperId, anOperName, anOperOrg);

        // 数据存盘,基本信息
        addCustMechBase(anOpenAccountInfo, custInfo.getCustNo(), anOperId, anOperName, anOperOrg);

        // 数据存盘,法人信息
        addCustMechLaw(anOpenAccountInfo, anCustFileItem, custInfo.getCustNo(), anOperId, anOperName, anOperOrg);

        // 数据存盘,营业执照
        addCustMechBusinLicence(anOpenAccountInfo, anCustFileItem, custInfo.getCustNo(), anOperId, anOperName,
                anOperOrg);

        // 数据存盘,银行账户
        addCustMechBankAccount(anOpenAccountInfo, anCustFileItem, custInfo.getCustNo(), anOperId, anOperName,
                anOperOrg);

        // 数据存盘,经办人信息
        addWeChatCustOperatorInfo(anOpenAccountInfo, anCustFileItem, custInfo.getCustNo(), anOperId, anOperName,
                anOperOrg);

        // 数据存盘,当前操作员关联客户
        custAndOperatorRelaService.insert(new CustOperatorRelation(anOperId, custInfo.getCustNo(), anOperOrg));

        // 回写客户编号
        anOpenAccountInfo.setCustNo(custInfo.getCustNo());
    }

    /**
     * 回写多个数据
     * 
     * @param anOpenAccountInfo
     * @param anOperId
     * @param anOperName
     * @param anOperOrg
     */
    private void createWeChatValidAccountAfter(final CustOpenAccountTmp anOpenAccountInfo, final Long anOperId,
            final String anOperName, final String anOperOrg, final CustOperatorInfo operatorInfo) {
        // 开户资料附件
        final Long anBatchNo = anOpenAccountInfo.getBatchNo();

        // 开户资料附件信息
        final Multimap<String, Object> anCustFileItem = ReflectionUtils
                .listConvertToMuiltMap(custFileItemService.findCustFiles(anBatchNo), "fileInfoType");

        // 数据存盘,客户资料
        final CustInfo custInfo = addCustInfoAfter(anOpenAccountInfo, anOperId, anOperName, anOperOrg);

        // 数据存盘,基本信息
        addCustMechBase(anOpenAccountInfo, custInfo.getCustNo(), anOperId, anOperName, anOperOrg);

        // 数据存盘,法人信息
        addCustMechLaw(anOpenAccountInfo, anCustFileItem, custInfo.getCustNo(), anOperId, anOperName, anOperOrg);

        // 数据存盘,营业执照
        addCustMechBusinLicence(anOpenAccountInfo, anCustFileItem, custInfo.getCustNo(), anOperId, anOperName,
                anOperOrg);

        // 数据存盘,银行账户
        addCustMechBankAccount(anOpenAccountInfo, anCustFileItem, custInfo.getCustNo(), anOperId, anOperName,
                anOperOrg);

        // 数据存盘,当前操作员关联客户
        custAndOperatorRelaService.insert(new CustOperatorRelation(anOperId, custInfo.getCustNo(), anOperOrg));

        // 数据存盘，联系人信息保存
        saveContacterInfo(anOpenAccountInfo, anOperId, anOperName, anOperOrg);

        // 企业信息绑定到平台创建的客户
        rebackOperatorInfo(anOpenAccountInfo, operatorInfo);
    }

    /**
     * 企业信息回写入操作员表
     * 
     * @param anOpenAccountInfo
     * @param operatorInfo
     */
    public void rebackOperatorInfo(final CustOpenAccountTmp anOpenAccountInfo, final CustOperatorInfo operatorInfo) {
        // 企业信息绑定到平台创建的客户
        operatorInfo.setCustNo(anOpenAccountInfo.getId());
        operatorInfo.setCustName(anOpenAccountInfo.getCustName());
        operatorInfo.setOperOrg(anOpenAccountInfo.getCustName());
        operatorInfo.setZipCode(anOpenAccountInfo.getZipCode());
        operatorInfo.setFaxNo(anOpenAccountInfo.getFax());
        operatorInfo.setAddress(anOpenAccountInfo.getAddress());
        this.operatorRequestService.updateByPrimaryKey(operatorInfo);
    }

    /**
     * 保存联系人信息
     * 
     * @param anOpenAccountInfo
     * @param anOperId
     * @param anOperName
     * @param anOperOrg
     */
    public void saveContacterInfo(final CustOpenAccountTmp anOpenAccountInfo, final Long anOperId,
            final String anOperName, final String anOperOrg) {
        final CustMechContacter contacter = new CustMechContacter();
        contacter.initContacterValue(anOpenAccountInfo);
        final CustOperatorInfo operatorInfo = this.operatorRequestService.selectByPrimaryKey(anOperId);
        contacter.setRegOperId(operatorInfo.getId());
        contacter.setRegOperName(operatorInfo.getName());
        contacter.setEmail(operatorInfo.getEmail());
        this.custMechContacterService.insert(contacter);

    }

    /*
     * 回写多个数据
     */
    private void createValidAccount(final CustOpenAccountTmp anOpenAccountInfo, final Long anOperId,
            final String anOperName, final String anOperOrg) {
        // 开户资料附件信息
        final Multimap<String, Object> anCustFileItem = ReflectionUtils.listConvertToMuiltMap(
                custFileItemService.findCustFiles(anOpenAccountInfo.getBatchNo()), "fileInfoType");
        // 数据存盘,客户资料
        final CustInfo custInfo = addCustInfo(anOpenAccountInfo, anOperId, anOperName, anOperOrg);
        // 新增经办人、操作员
        addCustOperatorInfo(anOpenAccountInfo, anCustFileItem, custInfo.getCustNo(), anOperId, anOperName, anOperOrg);
        // 回写客户编号
        anOpenAccountInfo.setCustNo(custInfo.getCustNo());
        // 数据存盘,基本信息
        addCustMechBase(anOpenAccountInfo, custInfo.getCustNo(), anOperId, anOperName, anOperOrg);
        // 数据存盘,法人信息
        addCustMechLaw(anOpenAccountInfo, anCustFileItem, custInfo.getCustNo(), anOperId, anOperName, anOperOrg);
        // 数据存盘,营业执照
        addCustMechBusinLicence(anOpenAccountInfo, anCustFileItem, custInfo.getCustNo(), anOperId, anOperName,
                anOperOrg);
        // 数据存盘,银行账户
        addCustMechBankAccount(anOpenAccountInfo, anCustFileItem, custInfo.getCustNo(), anOperId, anOperName,
                anOperOrg);
        // 数据存盘,当前操作员关联客户
        custAndOperatorRelaService.insert(new CustOperatorRelation(anOperId, custInfo.getCustNo(), anOperOrg));
        // 写入T_TEMP_CUST_ENROLL表
        addCustEnroll(anOpenAccountInfo, anOperOrg);

        // 若为微信开户
        if (!StringUtils.isEmpty(anOpenAccountInfo.getWechatOpenId())) {
            // 生成证书信息
            initCustCertinfo(anOpenAccountInfo, anOperOrg, anOperId, anOperName);
            // 绑定微信
            addBindWeChat(custInfo, anOperId, anOperOrg, anOperName, anOpenAccountInfo.getWechatOpenId());
            // 添加密码相关
            addPassword(anOpenAccountInfo, anOperId);
        }
    }

    /**
     * 添加密码相关
     */
    private void addPassword(final CustOpenAccountTmp anOpenAccountInfo, final Long anOperId) {

        final int passValidLimit = 1;
        final CustPassInfo dealPassInfo = new CustPassInfo(CustPasswordType.ORG_TRADE, passValidLimit, anOperId,
                anOpenAccountInfo.getDealPasswordSalt(), anOpenAccountInfo.getDealPassword());
        custPassService.insert(dealPassInfo);

        final CustPassInfo loginPassInfo = new CustPassInfo(CustPasswordType.ORG, passValidLimit, anOperId,
                anOpenAccountInfo.getLoginPasswordSalt(), anOpenAccountInfo.getLoginPassword());
        custPassService.insert(loginPassInfo);

    }

    /**
     * 经办人与当前微信绑定
     */
    private void addBindWeChat(final CustInfo anCustInfo, final Long anOperId, final String anOperOrg,
            final String anOperName, final String anOpenId) {
        BTAssert.isTrue(StringUtils.isNotBlank(anOpenId), "openid 不允许为空");
        final CustWeChatInfo weChatInfo = custWeChatService.selectByPrimaryKey(anOpenId);
        BTAssert.notNull(weChatInfo, "没有找到微信用户信息！");
        weChatInfo.setOperId(anOperId);
        weChatInfo.setOperName(anOperName);
        weChatInfo.setOperOrg(anOperOrg);
        weChatInfo.setModiDate(BetterDateUtils.getNumDate());
        weChatInfo.setModiTime(BetterDateUtils.getNumTime());
        weChatInfo.setModiOperId(anOperId);
        weChatInfo.setModiOperName(anOperName);
        weChatInfo.setCustNo(anCustInfo.getCustNo());
        weChatInfo.setBusinStatus("1");// 开户结束后设置为已完成状态;
        custWeChatService.updateByPrimaryKeySelective(weChatInfo);
    }

    /**
     * 生成证书信息
     */
    private void initCustCertinfo(final CustOpenAccountTmp anOpenAccountInfo, final String anOperOrg,
            final Long anOperId, final String anOperName) {
        final CustCertInfo certInfo = new CustCertInfo();
        certInfo.setSerialNo(
                Long.toUnsignedString(System.currentTimeMillis() * 10000 + SerialGenerator.randomInt(10000)));
        certInfo.setCustNo(anOpenAccountInfo.getCustNo());
        certInfo.setCustName(anOpenAccountInfo.getCustName());
        certInfo.setIdentNo(anOpenAccountInfo.getIdentNo());
        certInfo.setContName(anOpenAccountInfo.getOperName());
        certInfo.setContIdentType("0");
        certInfo.setContIdentNo("");
        certInfo.setContPhone(anOpenAccountInfo.getOperMobile());
        certInfo.setStatus("8"); // 微信端开户
        certInfo.setVersionUid("wechat");
        certInfo.setSubject("wechat" + anOpenAccountInfo.getCustNo());
        certInfo.setOperNo("-1");
        certInfo.setCertInfo("wechat" + anOpenAccountInfo.getCustNo());
        certInfo.setValidDate(BetterDateUtils.getNumDate());
        certInfo.setCreateDate(BetterDateUtils.getNumDate());
        certInfo.setToken("wechat" + anOpenAccountInfo.getCustNo());
        certInfo.setOperOrg(anOperOrg);
        certInfo.setRuleList(anOpenAccountInfo.getRole());
        certInfo.setCertId(-1l);
        certInfo.setRegOperId(anOperId);
        certInfo.setRegOperName(anOperName);
        certInfo.setRegDate(BetterDateUtils.getNumDate());
        certInfo.setRegTime(BetterDateUtils.getNumTime());
        certInfo.setModiOperId(anOperId);
        certInfo.setModiOperName(anOperName);
        certInfo.setModiDate(BetterDateUtils.getNumDate());
        certInfo.setModiTime(BetterDateUtils.getNumTime());
        certInfo.setPublishDate(BetterDateUtils.getNumDate());
        certInfo.setPublishMode(BetterDateUtils.getNumTime());
        certInfo.setDescription("wechat" + anOpenAccountInfo.getCustNo());
        certInfo.setEmail(anOpenAccountInfo.getOperEmail());
        custCertService.addCustCertInfo(certInfo);
    }

    /**
     * 写入T_TEMP_CUST_ENROLL表
     */
    private CustTempEnrollInfo addCustEnroll(final CustOpenAccountTmp anOpenAccountInfo, final String anOperOrg) {
        final CustTempEnrollInfo custEnrollInfo = new CustTempEnrollInfo();
        custEnrollInfo.initWeChatAddValue();
        custEnrollInfo.setCustName(anOpenAccountInfo.getCustName());
        custEnrollInfo.setIdentType(anOpenAccountInfo.getIdentType());
        custEnrollInfo.setIdentNo(anOpenAccountInfo.getIdentNo());
        custEnrollInfo.setCustNo(anOpenAccountInfo.getCustNo());
        custEnrollInfo.setContName(anOpenAccountInfo.getOperName());
        custEnrollInfo.setContIdentType(anOpenAccountInfo.getOperIdenttype());
        custEnrollInfo.setContIdentNo(anOpenAccountInfo.getOperIdentno());
        custEnrollInfo.setContPhone(anOpenAccountInfo.getOperPhone());
        custEnrollInfo.setContMobileNo(anOpenAccountInfo.getOperMobile());
        custEnrollInfo.setContEmail(anOpenAccountInfo.getOperEmail());
        custEnrollInfo.setStatus("1");
        custEnrollInfo.setOperOrg(anOperOrg);
        custEnrollInfo.setBankAccount(anOpenAccountInfo.getBankAcco());
        custEnrollInfo.setBankAcountName(anOpenAccountInfo.getBankAccoName());
        custEnrollInfo.setBankName(anOpenAccountInfo.getBankName());
        custEnrollService.insert(custEnrollInfo);
        return custEnrollInfo;
    }

    @SuppressWarnings("unused")
    private void addCustRelation(final CustOpenAccountTmp anOpenAccountInfo, final CustInfo anCustInfo,
            final String anOperOrg) {
        if (!StringUtils.isBlank(anOpenAccountInfo.getCoreList())) {
            final String[] anCoreList = StringUtils.split(anOpenAccountInfo.getCoreList(), ",");
            for (final String anCoreNo : anCoreList) {
                if (StringUtils.isNotBlank(anCoreNo)) {
                    final Long anCoreCustNo = Long.valueOf(anCoreNo.trim());
                    // 供应商开户与核心企业建立关系
                    final CustCertInfo anCustCertInfo = custCertService.findCertByOperOrg(anOperOrg);
                    if (UserUtils.supplierCustomer(anCustCertInfo)) {
                        final CustRelation custRelation = custRelationService.addCustRelation(anCustInfo, anCoreCustNo,
                                CustomerConstants.RELATE_TYPE_SUPPLIER_CORE, CustomerConstants.RELATE_STATUS_AUDIT);
                        // 写入银行账户信息
                        custRelation.setBankAcco(anOpenAccountInfo.getBankAcco());
                        custRelation.setBankAccoName(anOpenAccountInfo.getBankAccoName());
                        custRelationService.updateByPrimaryKeySelective(custRelation);
                    }
                    // 经销商开户与核心企业建立关系
                    if (UserUtils.sellerCustomer(anCustCertInfo)) {
                        custRelationService.addCustRelation(anCustInfo, anCoreCustNo,
                                CustomerConstants.RELATE_TYPE_SELLER_CORE, CustomerConstants.RELATE_STATUS_AUDIT);
                    }
                    // 核心企业开户写入字典表
                    if (UserUtils.coreCustomer(anCustCertInfo)) {
                        final DictInfo anDictInfo = dictService.findByCode("ScfCoreGroup");
                        final DictItemInfo anDictItem = new DictItemInfo(String.valueOf(anCustInfo.getCustNo()),
                                anCustInfo.getOperOrg(), anDictInfo.getId(), anCustInfo.getCustName());
                        dictItemService.insert(anDictItem);
                    }
                }
            }
        }
    }

    /*
     * 添加企业信息同步
     */
    private CustInfo addCustInfo(final CustOpenAccountTmp anOpenAccountInfo, final Long anOperId,
            final String anOperName, final String anOperOrg) {
        final CustInfo anCustInfo = new CustInfo();
        anCustInfo.setRegOperId(anOperId);
        anCustInfo.setRegOperName(anOperName);
        anCustInfo.setOperOrg(anOperOrg);
        // 生成客户号
        anCustInfo.setCustNo(SerialGenerator.getCustNo());
        anCustInfo.setIdentValid(true);
        anCustInfo.setCustType(CustomerConstants.CUSTOMER_TYPE_ENTERPRISE);// 客户类型:0-机构;1-个人;
        anCustInfo.setCustName(anOpenAccountInfo.getCustName());
        anCustInfo.setIdentType("1");
        anCustInfo.setIdentNo(anOpenAccountInfo.getBusinLicence());
        anCustInfo.setValidDate(anOpenAccountInfo.getBusinLicenceValidDate());
        anCustInfo.setRegDate(BetterDateUtils.getNumDate());
        anCustInfo.setRegTime(BetterDateUtils.getNumTime());
        // 客户状态；0正常，1冻结，9销户
        anCustInfo.setBusinStatus("0");
        anCustInfo.setLastStatus("0");
        anCustInfo.setVersion(0l);
        custAccountService.insert(anCustInfo);
        return anCustInfo;
    }

    /**
     * 同步企业信息
     * 
     * @param anOpenAccountInfo
     * @param anOperId
     * @param anOperName
     * @param anOperOrg
     * @return
     */
    private CustInfo addCustInfoAfter(final CustOpenAccountTmp anOpenAccountInfo, final Long anOperId,
            final String anOperName, final String anOperOrg) {
        final CustInfo anCustInfo = new CustInfo();
        anCustInfo.setRegOperId(anOperId);
        anCustInfo.setRegOperName(anOperName);
        anCustInfo.setOperOrg(anOperOrg);
        anCustInfo.setBusinLicence(anOpenAccountInfo.getBusinLicence());
        anCustInfo.setPhone(anOpenAccountInfo.getPhone());
        anCustInfo.setAddress(anOpenAccountInfo.getAddress());
        // 生成客户号
        anCustInfo.setCustNo(anOpenAccountInfo.getId());
        anCustInfo.setIdentValid(true);
        anCustInfo.setCustType(CustomerConstants.CUSTOMER_TYPE_ENTERPRISE);// 客户类型:0-机构;1-个人;
        anCustInfo.setCustName(anOpenAccountInfo.getCustName());
        anCustInfo.setCustType(anOpenAccountInfo.getCustType());
        anCustInfo.setIdentType("1");
        anCustInfo.setIdentNo(anOpenAccountInfo.getBusinLicence());
        anCustInfo.setValidDate(anOpenAccountInfo.getBusinLicenceValidDate());
        anCustInfo.setRegDate(BetterDateUtils.getNumDate());
        anCustInfo.setRegTime(BetterDateUtils.getNumTime());
        // 客户状态；0正常，1冻结，9销户
        anCustInfo.setBusinStatus("0");
        anCustInfo.setLastStatus("0");
        anCustInfo.setVersion(0l);
        custAccountService.insert(anCustInfo);
        return anCustInfo;
    }

    /**
     * 保存客户基本信息
     */
    private void addCustMechBase(final CustOpenAccountTmp anOpenAccountInfo, final Long anCustNo, final Long anOperId,
            final String anOperName, final String anOperOrg) {
        final CustMechBase anCustMechBaseInfo = new CustMechBase();
        anCustMechBaseInfo.setRegOperId(anOperId);
        anCustMechBaseInfo.setRegOperName(anOperName);
        anCustMechBaseInfo.setOperOrg(anOperOrg);
        anCustMechBaseInfo.setLawName(anOpenAccountInfo.getLawName());
        anCustMechBaseInfo.setLawIdentType(anOpenAccountInfo.getLawIdentType());
        anCustMechBaseInfo.setLawIdentNo(anOpenAccountInfo.getLawIdentNo());
        anCustMechBaseInfo.setLawValidDate(anOpenAccountInfo.getLawValidDate());
        anCustMechBaseInfo.setOrgCode(anOpenAccountInfo.getOrgCode());
        anCustMechBaseInfo.setBusinLicence(anOpenAccountInfo.getBusinLicence());
        anCustMechBaseInfo.setAddress(anOpenAccountInfo.getAddress());
        anCustMechBaseInfo.setPhone(anOpenAccountInfo.getPhone());
        anCustMechBaseInfo.setFax(anOpenAccountInfo.getFax());
        anCustMechBaseInfo.setVersion(0l);
        anCustMechBaseInfo.setZipCode(anOpenAccountInfo.getZipCode());
        custMechBaseService.addCustMechBase(anCustMechBaseInfo, anCustNo);
    }

    /**
     * 保存客户法人信息
     */
    private void addCustMechLaw(final CustOpenAccountTmp anOpenAccountInfo,
            final Multimap<String, Object> anCustFileItem, final Long anCustNo, final Long anOperId,
            final String anOperName, final String anOperOrg) {
        final CustMechLaw anCustMechLawInfo = new CustMechLaw();
        anCustMechLawInfo.setCustNo(anCustNo);
        anCustMechLawInfo.setRegOperId(anOperId);
        anCustMechLawInfo.setRegOperName(anOperName);
        anCustMechLawInfo.setOperOrg(anOperOrg);
        anCustMechLawInfo.setName(anOpenAccountInfo.getLawName());
        anCustMechLawInfo.setIdentType(anOpenAccountInfo.getLawIdentType());
        anCustMechLawInfo.setIdentNo(anOpenAccountInfo.getLawIdentNo());
        anCustMechLawInfo.setValidDate(anOpenAccountInfo.getLawValidDate());
        anCustMechLawInfo.setSex(
                IdcardUtils.getGenderByIdCard(anOpenAccountInfo.getLawIdentNo(), anOpenAccountInfo.getLawIdentType()));
        anCustMechLawInfo.setBirthdate(IdcardUtils.getBirthByIdCard(anOpenAccountInfo.getLawIdentNo()));
        anCustMechLawInfo.setVersion(0l);

        // 附件：法人身份证-头像面RepresentIdHeadFile
        final Collection headCollection = anCustFileItem.get("RepresentIdHeadFile");
        final List<CustFileItem> headFileList = new ArrayList(headCollection);
        // 附件：法人身份证-国徽面RepresentIdNationFile
        final Collection nationCollection = anCustFileItem.get("RepresentIdNationFile");
        final List<CustFileItem> nationFileList = new ArrayList(nationCollection);
        // 附件：法人身份证-手持证件RepresentIdHoldFile
        final Collection holdCollection = anCustFileItem.get("RepresentIdHoldFile");
        final List<CustFileItem> holdFileList = new ArrayList(holdCollection);
        // 企业三证附件信息同时处理
        if (headFileList.size() > 0 || nationFileList.size() > 0 || holdFileList.size() > 0) {
            final Long anNewBatchNo = CustFileUtils.findBatchNo();
            // 附件：法人身份证-头像面RepresentIdHeadFile,更新文件信息,同时写入文件认证信息
            saveCustFileItem(headFileList, "RepresentIdHeadFile", anCustNo, anNewBatchNo, anOperId);
            // 附件：法人身份证-国徽面RepresentIdNationFile,更新文件信息,同时写入文件认证信息
            saveCustFileItem(nationFileList, "RepresentIdNationFile", anCustNo, anNewBatchNo, anOperId);
            // 附件：法人身份证-手持证件RepresentIdHoldFile,更新文件信息,同时写入文件认证信息
            saveCustFileItem(holdFileList, "RepresentIdHoldFile", anCustNo, anNewBatchNo, anOperId);
            // 更新附件批次号
            anCustMechLawInfo.setBatchNo(anNewBatchNo);
        }
        custMechLawService.addCustMechLaw(anCustMechLawInfo, anCustNo);
    }

    /**
     * 保存营业执照
     */
    private void addCustMechBusinLicence(final CustOpenAccountTmp anOpenAccountInfo,
            final Multimap<String, Object> anCustFileItem, final Long anCustNo, final Long anOperId,
            final String anOperName, final String anOperOrg) {
        final CustMechBusinLicence anCustMechBusinLicenceInfo = new CustMechBusinLicence();
        anCustMechBusinLicenceInfo.setCustNo(anCustNo);
        anCustMechBusinLicenceInfo.setRegOperId(anOperId);
        anCustMechBusinLicenceInfo.setRegOperName(anOperName);
        anCustMechBusinLicenceInfo.setOperOrg(anOperOrg);
        anCustMechBusinLicenceInfo.setRegNo(anOpenAccountInfo.getBusinLicence());
        anCustMechBusinLicenceInfo.setCertifiedDate(anOpenAccountInfo.getBusinLicenceRegDate());
        anCustMechBusinLicenceInfo.setOrgCode(anOpenAccountInfo.getOrgCode());
        anCustMechBusinLicenceInfo.setLawName(anOpenAccountInfo.getLawName());
        anCustMechBusinLicenceInfo.setEndDate(anOpenAccountInfo.getBusinLicenceValidDate());
        // 税务登记证号
        anCustMechBusinLicenceInfo.setTaxNo(anOpenAccountInfo.getTaxNo());
        // 附件：组织机构代码证CustOrgCodeFile
        final Collection anOrgCodeCollection = anCustFileItem.get("CustOrgCodeFile");
        final List<CustFileItem> anOrgCodeFileItemList = new ArrayList(anOrgCodeCollection);
        // 附件：税务登记证CustTaxRegistFile
        final Collection anTaxRegistollection = anCustFileItem.get("CustTaxRegistFile");
        final List<CustFileItem> anTaxRegistFileItemList = new ArrayList(anTaxRegistollection);
        // 附件：营业执照CustBizLicenseFile
        final Collection anBizLicenseCollection = anCustFileItem.get("CustBizLicenseFile");
        final List<CustFileItem> anBizLicenseFileItemList = new ArrayList(anBizLicenseCollection);
        // 企业三证附件信息同时处理
        if (anOrgCodeFileItemList.size() > 0 || anTaxRegistFileItemList.size() > 0
                || anBizLicenseFileItemList.size() > 0) {
            final Long anNewBatchNo = CustFileUtils.findBatchNo();
            // 附件：组织机构代码证CustOrgCodeFile,更新文件信息,同时写入文件认证信息
            saveCustFileItem(anOrgCodeFileItemList, "CustOrgCodeFile", anCustNo, anNewBatchNo, anOperId);
            // 附件：税务登记证CustTaxRegistFile,更新文件信息,同时写入文件认证信息
            saveCustFileItem(anTaxRegistFileItemList, "CustTaxRegistFile", anCustNo, anNewBatchNo, anOperId);
            // 附件：营业执照CustBizLicenseFile,更新文件信息,同时写入文件认证信息
            saveCustFileItem(anBizLicenseFileItemList, "CustBizLicenseFile", anCustNo, anNewBatchNo, anOperId);
            // 更新附件批次号
            anCustMechBusinLicenceInfo.setBatchNo(anNewBatchNo);
        }
        custMechBusinLicenceService.addBusinLicence(anCustMechBusinLicenceInfo, anCustNo);
    }

    private void addCustMechBankAccount(final CustOpenAccountTmp anOpenAccountInfo,
            final Multimap<String, Object> anCustFileItem, final Long anCustNo, final Long anOperId,
            final String anOperName, final String anOperOrg) {
        final CustMechBankAccount anCustMechBankAccountInfo = new CustMechBankAccount();
        anCustMechBankAccountInfo.setCustNo(anCustNo);
        anCustMechBankAccountInfo.setRegOperId(anOperId);
        anCustMechBankAccountInfo.setRegOperName(anOperName);
        anCustMechBankAccountInfo.setOperOrg(anOperOrg);
        anCustMechBankAccountInfo.setIsDefault(true);
        anCustMechBankAccountInfo.setTradeAcco("");
        anCustMechBankAccountInfo.setBankNo(anOpenAccountInfo.getBankNo());
        anCustMechBankAccountInfo.setBankName(anOpenAccountInfo.getBankName());
        anCustMechBankAccountInfo.setBankAcco(anOpenAccountInfo.getBankAcco());
        anCustMechBankAccountInfo.setBankAccoName(anOpenAccountInfo.getBankAccoName());
        // 银行帐号省市添加
        if (anOpenAccountInfo.getProvinceName() != null && anOpenAccountInfo.getCityName() != null) {
            anCustMechBankAccountInfo.setCountyName(anOpenAccountInfo.getProvinceName());
            anCustMechBankAccountInfo.setCityName(anOpenAccountInfo.getCityName());
        }
        // 添加银行属性名称
        if (anOpenAccountInfo.getBankPropertyName() != null && !anOpenAccountInfo.getBankPropertyName().equals("")) {
            anCustMechBankAccountInfo.setBankPropertyName(anOpenAccountInfo.getBankPropertyName());
        }
        anCustMechBankAccountInfo.setBankBranch(anOpenAccountInfo.getPaySysNum());
        anCustMechBankAccountInfo.setNetNo("");
        anCustMechBankAccountInfo.setPayCenter("");
        anCustMechBankAccountInfo.setAuthStatus("0");
        anCustMechBankAccountInfo.setSignStatus("0");
        anCustMechBankAccountInfo.setIdentType(anOpenAccountInfo.getIdentType());
        anCustMechBankAccountInfo.setIdentNo(anOpenAccountInfo.getIdentNo());
        anCustMechBankAccountInfo.setFlag("");
        anCustMechBankAccountInfo.setBakupAcco("");
        anCustMechBankAccountInfo.setCityNo(anOpenAccountInfo.getBankCityno());
        anCustMechBankAccountInfo.setAccoStatus("0");
        anCustMechBankAccountInfo.setVersion(0l);
        anCustMechBankAccountInfo.setPaySysNum(anOpenAccountInfo.getPaySysNum());
        anCustMechBankAccountInfo.setOpenLicense(anOpenAccountInfo.getOpenLicense());
        // 附件：银行账户开户许可证CustBankOpenLicenseFile
        final Collection anCollection = anCustFileItem.get("CustBankOpenLicenseFile");
        final List<CustFileItem> anFileItemList = new ArrayList(anCollection);
        if (anFileItemList.size() > 0) {
            final Long anNewBatchNo = CustFileUtils.findBatchNo();
            // 更新文件信息,同时写入文件认证信息
            saveCustFileItem(anFileItemList, "CustBankOpenLicenseFile", anCustNo, anNewBatchNo, anOperId);
            // 更新附件批次号
            anCustMechBankAccountInfo.setBatchNo(anNewBatchNo);
        }
        custMechBankAccountService.addCustMechBankAccount(anCustMechBankAccountInfo, anCustNo);
    }

    private void addWeChatCustOperatorInfo(final CustOpenAccountTmp anOpenAccountInfo,
            final Multimap<String, Object> anCustFileItem, final Long anCustNo, final Long anOperId,
            final String anOperName, final String anOperOrg) {
        final CustOperatorInfo anCustOperatorInfo = new CustOperatorInfo();
        anCustOperatorInfo.setOperOrg(anOperOrg);
        anCustOperatorInfo.setId(anOperId);
        anCustOperatorInfo.setName(anOperName);
        anCustOperatorInfo.setIdentType(anOpenAccountInfo.getOperIdenttype());
        anCustOperatorInfo.setIdentNo(anOpenAccountInfo.getOperIdentno());
        anCustOperatorInfo.setMobileNo(anOpenAccountInfo.getOperMobile());
        anCustOperatorInfo.setPhone(anOpenAccountInfo.getOperPhone());
        anCustOperatorInfo.setIdentClass(anOpenAccountInfo.getOperIdenttype());
        anCustOperatorInfo.setValidDate(anOpenAccountInfo.getOperValiddate());
        anCustOperatorInfo.setStatus("1");
        anCustOperatorInfo.setLastStatus("1");
        anCustOperatorInfo.setClerkMan("2");
        // anCustOperatorInfo.setSex(IdcardUtils.getGenderByIdCard(anCustOperatorInfo.getIdentNo(),
        // anCustOperatorInfo.getIdentType()));
        anCustOperatorInfo.setRegDate(BetterDateUtils.getNumDate());
        anCustOperatorInfo.setModiDate(BetterDateUtils.getNumDateTime());
        anCustOperatorInfo.setFaxNo(anOpenAccountInfo.getOperFaxNo());
        anCustOperatorInfo.setAddress(anOpenAccountInfo.getAddress());
        anCustOperatorInfo.setEmail(anOpenAccountInfo.getOperEmail());
        anCustOperatorInfo.setZipCode(anOpenAccountInfo.getZipCode());
        custOperatorService.insert(anCustOperatorInfo);
        // 附件：经办人brokerIdFile
        final Collection anCollection = anCustFileItem.get("brokerIdFile");
        final List<CustFileItem> anFileItemList = new ArrayList(anCollection);
        if (anFileItemList.size() > 0) {
            final Long anNewBatchNo = CustFileUtils.findBatchNo();
            // 更新文件信息,同时写入文件认证信息
            saveCustFileItem(anFileItemList, "brokerIdFile", anCustNo, anNewBatchNo, anOperId);
        }
    }

    /**
     * 新增经办人信息或补充经办人附件
     */
    private void addCustOperatorInfo(final CustOpenAccountTmp anOpenAccountInfo,
            final Multimap<String, Object> anCustFileItem, final Long anCustNo, final Long anOperId,
            final String anOperName, final String anOperOrg) {
        final CustOperatorInfo anCustOperatorInfo = new CustOperatorInfo();
        anCustOperatorInfo.setOperOrg(anOperOrg);
        // anCustOperatorInfo.setId(SerialGenerator.getLongValue(SerialGenerator.OPERATOR_ID));
        anCustOperatorInfo.setName(anOpenAccountInfo.getOperName());
        anCustOperatorInfo.setIdentType(anOpenAccountInfo.getOperIdenttype());
        anCustOperatorInfo.setIdentNo(anOpenAccountInfo.getOperIdentno());
        anCustOperatorInfo.setMobileNo(anOpenAccountInfo.getOperMobile());
        anCustOperatorInfo.setPhone(anOpenAccountInfo.getOperPhone());
        anCustOperatorInfo.setIdentClass(anOpenAccountInfo.getOperIdenttype());
        anCustOperatorInfo.setValidDate(anOpenAccountInfo.getOperValiddate());
        anCustOperatorInfo.setStatus("1");
        anCustOperatorInfo.setLastStatus("1");
        // anCustOperatorInfo.setSex(IdcardUtils.getGenderByIdCard(anCustOperatorInfo.getIdentNo(),
        // anCustOperatorInfo.getIdentType()));
        anCustOperatorInfo.setModiDate(BetterDateUtils.getNumDateTime());
        anCustOperatorInfo.setFaxNo(anOpenAccountInfo.getOperFaxNo());
        anCustOperatorInfo.setAddress(anOpenAccountInfo.getAddress());
        anCustOperatorInfo.setEmail(anOpenAccountInfo.getOperEmail());
        anCustOperatorInfo.setZipCode(anOpenAccountInfo.getZipCode());
        // 设置为对外经办人
        anCustOperatorInfo.setClerkMan("1");

        // 若为微信，需新增操作员
        if (!StringUtils.isEmpty(anOpenAccountInfo.getWechatOpenId())) {
            anCustOperatorInfo.setId(anOperId);
            anCustOperatorInfo.setRegDate(BetterDateUtils.getNumDate());
            // 设置登录帐号
            anCustOperatorInfo.setOperCode(anOpenAccountInfo.getLoginUserName());
            custOperatorService.insert(anCustOperatorInfo);
        } // 若为PC，更新操作员信息
        else {
            final CustOperatorInfo operatorInfo = Collections3
                    .getFirst(custOperatorService.selectByProperty("mobileNo", anOpenAccountInfo.getOperMobile()));
            BTAssert.notNull(operatorInfo, "未找到对应操作员信息!");
            anCustOperatorInfo.setId(operatorInfo.getId());
            custOperatorService.updateByPrimaryKeySelective(anCustOperatorInfo);
        }

        // 附件：经办人身份证-头像面BrokerIdHeadFile
        final Collection brokerIdHeadFile = anCustFileItem.get("BrokerIdHeadFile");
        final List<CustFileItem> brokerIdHeadFileList = new ArrayList(brokerIdHeadFile);
        // 附件：经办人身份证-国徽面BrokerIdNationFile
        final Collection brokerIdNationFile = anCustFileItem.get("BrokerIdNationFile");
        final List<CustFileItem> brokerIdNationFileList = new ArrayList(brokerIdNationFile);
        // 附件：经办人身份证-手持证件BrokerIdHoldFile
        final Collection brokerIdHoldFile = anCustFileItem.get("BrokerIdHoldFile");
        final List<CustFileItem> brokerIdHoldFileList = new ArrayList(brokerIdHoldFile);
        // 企业三证附件信息同时处理
        if (brokerIdHeadFileList.size() > 0 || brokerIdNationFileList.size() > 0 || brokerIdHoldFileList.size() > 0) {
            final Long anNewBatchNo = CustFileUtils.findBatchNo();
            // 附件：经办人身份证-头像面BrokerIdHeadFile,更新文件信息,同时写入文件认证信息
            saveCustFileItem(brokerIdHeadFileList, "BrokerIdHeadFile", anCustNo, anNewBatchNo, anOperId);
            // 附件：经办人身份证-国徽面BrokerIdNationFile,更新文件信息,同时写入文件认证信息
            saveCustFileItem(brokerIdNationFileList, "BrokerIdNationFile", anCustNo, anNewBatchNo, anOperId);
            // 附件：经办人身份证-手持证件BrokerIdHoldFile,更新文件信息,同时写入文件认证信息
            saveCustFileItem(brokerIdHoldFileList, "BrokerIdHoldFile", anCustNo, anNewBatchNo, anOperId);
        }
    }

    /**
     * 更新文件信息
     *
     * @param anCustFileItem
     * @param anFileInfoType
     * @param anCustNo
     * @param anBatchNo
     * @param anOperId
     */
    private void saveCustFileItem(final List<CustFileItem> anCustFileItem, final String anFileInfoType,
            final Long anCustNo, final Long anBatchNo, final Long anOperId) {
        if (anCustFileItem.size() > 0) {
            // 写入文件信息
            for (final CustFileItem fileItem : anCustFileItem) {
                addCustFileItem(fileItem, anBatchNo);
            }
            // 操作员编码
            final String anOperCode = custOperatorService.selectByPrimaryKey(anOperId).getId().toString();
            // 写入文件认证信息
            addCustFileAduit(anCustNo, anBatchNo, anCustFileItem.size(), anFileInfoType, anOperCode);
        }
    }

    private void addCustFileItem(final CustFileItem anCustFileItem, final Long anBatchNo) {
        final CustFileItem fileItem = new CustFileItem();
        BeanMapper.copy(anCustFileItem, fileItem);
        fileItem.setBatchNo(anBatchNo);
        fileItem.setId(SerialGenerator.getLongValue("CustFileItem.id"));
        custFileItemService.insert(fileItem);
    }

    /**
     * 写入文件认证信息
     *
     * @param anCustNo
     * @param anBatchNo
     * @param anFileCount
     * @param anFileInfoType
     * @param anOperCode
     */
    private void addCustFileAduit(final Long anCustNo, final Long anBatchNo, final int anFileCount,
            final String anFileInfoType, final String anOperCode) {
        final CustFileAduit anFileAudit = new CustFileAduit();
        anFileAudit.setId(anBatchNo);
        anFileAudit.setBatchNo(anBatchNo);
        anFileAudit.setCustNo(anCustNo);
        anFileAudit.setFileCount(anFileCount);
        anFileAudit.setAuditStatus("1");
        anFileAudit.setWorkType(anFileInfoType);
        anFileAudit.setDescription("");
        anFileAudit.setRegDate(BetterDateUtils.getNumDate());
        anFileAudit.setRegTime(BetterDateUtils.getNumTime());
        anFileAudit.setOperNo(anOperCode);
        custFileAuditService.insert(anFileAudit);
    }

    public void checkAccountInfoValid(final CustOpenAccountTmp anOpenAccountInfo) {
        // 检查开户资料入参
        checkAccountInfoParams(anOpenAccountInfo);

        // 检查申请机构名称是否存在
        if (checkCustExistsByCustName(anOpenAccountInfo.getCustName()) == true) {
            logger.warn("申请机构名称已存在");
            throw new BytterTradeException(40001, "申请机构名称已存在");
        }

        // 检查组织机构代码证是否存在
        if (checkCustExistsByOrgCode(anOpenAccountInfo.getOrgCode()) == true) {
            logger.warn("组织机构代码证已存在");
            throw new BytterTradeException(40001, "组织机构代码证已存在");
        }

        // 检查营业执照号码是否存在
        if (checkCustExistsByBusinLicence(anOpenAccountInfo.getBusinLicence()) == true) {
            logger.warn("营业执照号码已存在");
            throw new BytterTradeException(40001, "营业执照号码已存在");
        }

        // 检查银行账号是否存在
        if (checkCustExistsByBankAccount(anOpenAccountInfo.getBankAcco()) == true) {
            logger.warn("银行账号已存在");
            throw new BytterTradeException(40001, "银行账号已存在");
        }

        // 检查是否黑名单
        final String anFlag = blacklistService.checkBlacklistExists(anOpenAccountInfo.getCustName(),
                anOpenAccountInfo.getOrgCode(), anOpenAccountInfo.getLawName());
        if (StringUtils.equals(anFlag, "1")) {
            logger.warn("从黑名单库中检测到当前客户开户资料信息,请确认!");
            throw new BytterTradeException(40001, "从黑名单库中检测到当前客户开户资料信息,请确认!");
        }
    }

    /**
     * 检查账户信息入参
     * 
     * @param anOpenAccountInfo
     */
    public void checkAccountInfoValidAfter(final CustOpenAccountTmp anOpenAccountInfo) throws Exception {
        // 检查开户资料入参
        checkAccountInfoParamsAfter(anOpenAccountInfo);

        // 检查申请机构名称是否存在
        if (checkCustExistsByCustName(anOpenAccountInfo.getCustName()) == true) {
            logger.warn("申请机构名称已存在");
            throw new BytterTradeException(40001, "申请机构名称已存在");
        }

        // 检查组织机构代码证是否存在
        if (checkCustExistsByOrgCode(anOpenAccountInfo.getOrgCode()) == true) {
            logger.warn("组织机构代码证已存在");
            throw new BytterTradeException(40001, "组织机构代码证已存在");
        }

        // 检查营业执照号码是否存在
        if (checkCustExistsByBusinLicence(anOpenAccountInfo.getBusinLicence()) == true) {
            logger.warn("营业执照号码已存在");
            throw new BytterTradeException(40001, "营业执照号码已存在");
        }

        // 检查银行账号是否存在
        if (checkCustExistsByBankAccount(anOpenAccountInfo.getBankAcco()) == true) {
            logger.warn("银行账号已存在");
            throw new BytterTradeException(40001, "银行账号已存在");
        }

        // 检查是否黑名单
        final String anFlag = blacklistService.checkBlacklistExists(anOpenAccountInfo.getCustName(),
                anOpenAccountInfo.getOrgCode(), anOpenAccountInfo.getLawName());
        if (StringUtils.equals(anFlag, "1")) {
            logger.warn("从黑名单库中检测到当前客户开户资料信息,请确认!");
            throw new BytterTradeException(40001, "从黑名单库中检测到当前客户开户资料信息,请确认!");
        }
    }

    /**
     * 检查申请机构名称是否存在
     */
    public boolean checkCustExistsByCustName(final String anCustName) {
        return custAccountService.selectByProperty("custName", anCustName).size() > 0;
    }

    /**
     * 检查组织机构代码证是否存在
     */
    public boolean checkCustExistsByOrgCode(final String anOrgCode) {

        return custMechBaseService.selectByProperty("orgCode", anOrgCode).size() > 0;
    }

    /**
     * 检查营业执照号码是否存在
     */
    public boolean checkCustExistsByBusinLicence(final String anBusinLicence) {

        return custMechBaseService.selectByProperty("businLicence", anBusinLicence).size() > 0;
    }

    /**
     * 检查银行账号是否存在
     */
    public boolean checkCustExistsByBankAccount(final String anBankAccount) {

        return custMechBankAccountService.selectByProperty("bankAcco", anBankAccount).size() > 0;
    }

    /**
     * 检查邮箱是否已注册
     */
    public boolean checkCustExistsByEmail(final String anEmail) {
        return custOperatorService.selectByProperty("email", anEmail).size() > 0;
    }

    /**
     * 检查手机号码是否已注册
     */
    public boolean checkCustExistsByMobileNo(final String anMobileNo) {
        return custOperatorService.selectByProperty("mobileNo", anMobileNo).size() > 0;
    }

    private void checkAccountInfoParams(final CustOpenAccountTmp anOpenAccountInfo) {
        // 客户资料检查
        BTAssert.notNull(anOpenAccountInfo.getCustName(), "申请机构名称不能为空");
        BTAssert.notNull(anOpenAccountInfo.getOrgCode(), "组织机构代码证不能为空");
        BTAssert.notNull(anOpenAccountInfo.getBusinLicence(), "营业执照号码不能为空");
        BTAssert.notNull(anOpenAccountInfo.getBusinLicenceValidDate(), "营业执照有效期不能为空");
        BTAssert.notNull(anOpenAccountInfo.getZipCode(), "邮政编码不能为空");
        BTAssert.notNull(anOpenAccountInfo.getAddress(), "联系地址不能为空");
        BTAssert.notNull(anOpenAccountInfo.getPhone(), "业务联系电话不能为空");
        BTAssert.notNull(anOpenAccountInfo.getFax(), "传真号码不能为空");
        // 交收行信息检查
        BTAssert.notNull(anOpenAccountInfo.getBankAccoName(), "银行账户名不能为空");
        BTAssert.notNull(anOpenAccountInfo.getBankAcco(), "银行账户不能为空");
        BTAssert.notNull(anOpenAccountInfo.getBankNo(), "所属银行不能为空");
        BTAssert.notNull(anOpenAccountInfo.getBankCityno(), "开户银行所在地不能为空");
        BTAssert.notNull(anOpenAccountInfo.getBankName(), "开户银行全称不能为空");
        // 经办人信息检查
        BTAssert.notNull(anOpenAccountInfo.getOperName(), "经办人姓名不能为空");
        BTAssert.notNull(anOpenAccountInfo.getOperIdenttype(), "经办人证件类型不能为空");
        BTAssert.notNull(anOpenAccountInfo.getOperIdentno(), "经办人证件号码不能为空");
        BTAssert.notNull(anOpenAccountInfo.getOperValiddate(), "经办人证件有效期不能为空");
        BTAssert.notNull(anOpenAccountInfo.getOperMobile(), "经办人手机号码不能为空");
        BTAssert.notNull(anOpenAccountInfo.getOperEmail(), "经办人邮箱不能为空");
        BTAssert.notNull(anOpenAccountInfo.getOperPhone(), "经办人联系电话不能为空");
        // 法人信息检查
        BTAssert.notNull(anOpenAccountInfo.getLawName(), "法人姓名不能为空");
        BTAssert.notNull(anOpenAccountInfo.getLawIdentType(), "法人证件类型不能为空");
        BTAssert.notNull(anOpenAccountInfo.getLawIdentNo(), "法人证件号码不能为空");
        BTAssert.notNull(anOpenAccountInfo.getLawValidDate(), "法人证件有效期不能为空");
    }

    /**
     * 检查信息是否符合规则
     * 
     * @param anOpenAccountInfo
     */
    private void checkAccountInfoParamsAfter(final CustOpenAccountTmp anOpenAccountInfo) {
        // 客户资料检查
        BTAssert.notNull(anOpenAccountInfo.getCustName(), "申请机构名称不能为空");
        BTAssert.notNull(anOpenAccountInfo.getOrgCode(), "组织机构代码证不能为空");
        BTAssert.notNull(anOpenAccountInfo.getBusinLicence(), "营业执照号码不能为空");
        BTAssert.notNull(anOpenAccountInfo.getBusinLicenceValidDate(), "营业执照有效期不能为空");
        BTAssert.notNull(anOpenAccountInfo.getZipCode(), "邮政编码不能为空");
        BTAssert.notNull(anOpenAccountInfo.getAddress(), "联系地址不能为空");
        BTAssert.notNull(anOpenAccountInfo.getPhone(), "业务联系电话不能为空");
        BTAssert.notNull(anOpenAccountInfo.getFax(), "传真号码不能为空");
        // 交收行信息检查
        BTAssert.notNull(anOpenAccountInfo.getBankAccoName(), "银行账户名不能为空");
        BTAssert.notNull(anOpenAccountInfo.getBankAcco(), "银行账户不能为空");
        BTAssert.notNull(anOpenAccountInfo.getBankNo(), "所属银行不能为空");
        BTAssert.notNull(anOpenAccountInfo.getBankCityno(), "开户银行所在地不能为空");
        BTAssert.notNull(anOpenAccountInfo.getBankName(), "开户银行全称不能为空");

        // 法人信息检查
        BTAssert.notNull(anOpenAccountInfo.getLawName(), "法人姓名不能为空");
        BTAssert.notNull(anOpenAccountInfo.getLawIdentType(), "法人证件类型不能为空");
        BTAssert.notNull(anOpenAccountInfo.getLawIdentNo(), "法人证件号码不能为空");
        BTAssert.notNull(anOpenAccountInfo.getLawValidDate(), "法人证件有效期不能为空");
    }

    /**
     * 读取开户的临时文件信息，用于远程开通业务
     *
     * @param anCustNo
     *            客户编号
     * @return
     */
    public Map<String, Object> findOpenTempAccountInfo(final Long anCustNo) {
        // Map<String, Object> result = null;
        if (anCustNo != null && anCustNo.longValue() > 10) {
            final List<CustOpenAccountTmp> tmpList = this.selectByProperty("custNo", anCustNo);
            if (Collections3.isEmpty(tmpList) == false) {
                final CustOpenAccountTmp tmpAccount = Collections3.getFirst(tmpList);
                return BeanMapper.map(tmpAccount, HashMap.class);
            }
        }

        return new HashMap();
    }

    /**
     * 开户申请提交
     */
    public CustOpenAccountTmp saveOpenAccountApplySubmit(final CustOpenAccountTmp anOpenAccountInfo,
            final Long anOperId, final String anFileList) {
        logger.info("Begin to Commit Open Account Apply");
        // 检查重复提交
        checkRepeatSubmit(anOpenAccountInfo);
        // 填充操作员信息
        fillOperatorByOperId(anOperId, anOpenAccountInfo);
        // 检查开户资料合法性
        checkAccountInfoValid(anOpenAccountInfo);
        // 检查联行号不存在而银行全称正确情况，则可通过银行全称再获取一遍联行号
        if (StringUtils.isBlank(anOpenAccountInfo.getPaySysNum())) {
            final SysNapsBankCode bankCode = bankCodeService
                    .findSysBankCodeInfoByBankName(anOpenAccountInfo.getBankName());
            if (bankCode == null) {
                throw new BytterTradeException("银行全称输入不正确，请检查");
            } else {
                anOpenAccountInfo.setPaySysNum(bankCode.getPaySysNum());
            }
        }

        // 检查联行号对应的银行名称与所输入的银行全称是否一致
        bankCodeService.checkBankCode(anOpenAccountInfo.getPaySysNum(), anOpenAccountInfo.getBankName());
        // 初始化参数设置
        initAddValue(anOpenAccountInfo, CustomerConstants.TMP_TYPE_TEMPSTORE, CustomerConstants.TMP_STATUS_OWN);
        // 设置开户类型,"0"--PC自主开户
        anOpenAccountInfo.setDataSource(CustomerConstants.OPEN_ACCOUNT_TYPE_PC_OWN);
        // 处理附件
        anOpenAccountInfo
                .setBatchNo(custFileItemService.updateCustFileItemInfo(anFileList, anOpenAccountInfo.getBatchNo()));
        // 数据存盘,开户资料暂存
        this.insert(anOpenAccountInfo);
        return anOpenAccountInfo;
    }

    /**
     * 后端检查重复提交--使用申请机构名称
     */
    public void checkRepeatSubmit(final CustOpenAccountTmp anOpenAccountInfo) {
        if (this.selectByProperty("custName", anOpenAccountInfo.getCustName()).size() > 0) {
            logger.warn("此申请机构已提交申请");
            throw new BytterTradeException(40001, "此申请机构已提交申请，请勿重复提交");
        }
    }

    /**
     * 填充操作员信息
     */
    private void fillOperatorByOperId(final Long anOperId, final CustOpenAccountTmp anCustOpenAccountTmp) {
        final CustOperatorInfo anOperator = custOperatorService.selectByPrimaryKey(anOperId);
        BTAssert.notNull(anOperator, "未找到操作员信息！");
        anCustOpenAccountTmp.setOperName(anOperator.getName());
        anCustOpenAccountTmp.setOperIdenttype(anOperator.getIdentType());
        anCustOpenAccountTmp.setOperIdentno(anOperator.getIdentNo());
        anCustOpenAccountTmp.setOperValiddate(anOperator.getValidDate());
        anCustOpenAccountTmp.setOperMobile(anOperator.getMobileNo());
        anCustOpenAccountTmp.setOperEmail(anOperator.getEmail());
        anCustOpenAccountTmp.setOperPhone(anOperator.getPhone());
        anCustOpenAccountTmp.setOperFaxNo(anOperator.getFaxNo());
    }

    /**
     * 微信检查入参
     */
    private void wechatCheckAccountInfoValid(final CustOpenAccountTmp anOpenAccountInfo) {
        BTAssert.notNull(anOpenAccountInfo.getCustName(), "企业名称不能为空");
        BTAssert.notNull(anOpenAccountInfo.getOperName(), "经办人姓名不能为空");
        BTAssert.notNull(anOpenAccountInfo.getOperMobile(), "经办人手机号码不能为空");
        BTAssert.notNull(anOpenAccountInfo.getOperEmail(), "经办人邮箱不能为空");

        // 检查申请机构名称是否存在
        if (checkCustExistsByCustName(anOpenAccountInfo.getCustName()) == true) {
            logger.warn("申请机构名称已存在");
            throw new BytterTradeException(40001, "申请机构名称已存在");
        }
        if (checkCustExistsByEmail(anOpenAccountInfo.getOperEmail()) == true) {
            logger.warn("经办人邮箱已存在");
            throw new BytterTradeException(40001, "经办人邮箱已存在");
        }
        if (checkCustExistsByEmail(anOpenAccountInfo.getOperEmail()) == true) {
            logger.warn("经办人邮箱已存在");
            throw new BytterTradeException(40001, "经办人邮箱已存在");
        }
        if (checkCustExistsByMobileNo(anOpenAccountInfo.getOperMobile()) == true) {
            logger.warn("经办人手机号已存在");
            throw new BytterTradeException(40001, "经办人手机号已存在");
        }
    }

    /**
     * 通过微信唯一标识查询开户信息
     */
    public CustOpenAccountTmp findAccountTmpInfo(final String anOpenId) {
        // 检查入参
        checkParameter(anOpenId, "请关注微信公众号[qiejftest]后再进行开户!");
        final CustOpenAccountTmp accountTmpInfo = Collections3
                .getFirst(this.selectByProperty("wechatOpenId", anOpenId));
        return accountTmpInfo;
    }

    private void checkParameter(final String anKey, final String anMessage) {
        if (StringUtils.isBlank(anKey)) {
            logger.warn(anMessage);
            throw new BytterTradeException(40001, anMessage);
        }
    }

    /**
     * 根据开户id和文件id保存附件
     */
    public CustFileItem saveSingleFileLink(final Long anId, final String anFileTypeName, final String anFileMediaId) {
        final CustOpenAccountTmp custOpenInfo = this.selectByPrimaryKey(anId);
        BTAssert.notNull(custOpenInfo, "无法获取开户信息");
        final CustFileItem fileItem = custWeChatService.saveWechatFile(anFileTypeName, anFileMediaId);
        custOpenInfo.setBatchNo(
                custFileItemService2.updateCustFileItemInfo(fileItem.getId().toString(), custOpenInfo.getBatchNo()));
        this.updateByPrimaryKey(custOpenInfo);
        return fileItem;
    }

    /**
     * 根据batchNo生成对应文件类型Map Json对象(微信使用)
     */
    public Map<String, Object> findAccountFileByBatChNo(final Long anBatchNo) {
        final Map<String, Object> fileMap = new HashMap<String, Object>();
        final List<CustFileItem> fileList = custFileItemService.findCustFiles(anBatchNo);
        final String[] fileInfoTypes = { "CustBizLicenseFile", "CustOrgCodeFile", "CustTaxRegistFile",
                "CustCreditCodeFile", "CustBankOpenLicenseFile", "BrokerIdHeadFile", "BrokerIdNationFile",
                "BrokerIdHoldFile", "RepresentIdHeadFile", "RepresentIdNationFile", "RepresentIdHoldFile",
                "CustOpenAccountFilePack" };
        for (final String anFileInfoType : fileInfoTypes) {
            // 默认数据
            final CustFileItem defaultFile = new CustFileItem();
            defaultFile.setFileInfoType(anFileInfoType);
            // fileMap.put(anFileInfoType, defaultFile);
            // 遍历文件，若存在则放入
            for (final CustFileItem anFile : fileList) {
                if (StringUtils.equals(anFileInfoType, anFile.getFileInfoType())) {
                    fileMap.put(anFileInfoType, anFile);
                }
            }
        }
        return fileMap;
    }

    /**
     * 根据openId查询开户申请状态，返回对应值，供页面相应跳转使用
     * 
     * @param anOpenId
     * @return
     */
    public String findOpenAccountStatus(final String anOpenId) {
        final Map<String, Object> conditionMap = new HashMap<>();
        conditionMap.put("wechatOpenId", anOpenId);

        final CustOpenAccountTmp openAccountTmp = Collections3.getFirst(this.selectByProperty(conditionMap));

        if (openAccountTmp == null) {
            return "0";
        } else {
            final CustInsteadApply custInsteadApply = custInsteadService
                    .findInsteadApplyByAccountTmpId(openAccountTmp.getId());

            if (custInsteadApply != null) {
                if (StringUtils.equals(custInsteadApply.getBusinStatus(), "4")) {
                    return "2";
                }
                return "1";
            } else {

                return "0";
            }
        }
    }

    /**
     * 发送手机短信验证码
     */
    public String sendValidMessage(final String anMobileNo) {
        BTAssert.isTrue(StringUtils.isNotBlank(anMobileNo), "手机号码不允许为空！");
        final VerifyCode verifyCode = verificationCodeService.sendVerifyCode(anMobileNo,
                VerifyCodeType.OPEN_ACCOUNT_PASSWORD);
        BTAssert.notNull(verifyCode, "没有生成验证码！");
        JedisUtils.delObject(SmsConstants.smsOpenAccountVerifyCodePrefix + anMobileNo);
        JedisUtils.setObject(SmsConstants.smsOpenAccountVerifyCodePrefix + anMobileNo, verifyCode,
                SmsConstants.SEC_600);
        return AjaxObject.newOk("发送验证码成功").toJson();
    }

    /**
     * 根据operOrg查询Apply状态
     */
    public String findInsteadApplyStatus() {
        final CustInsteadApply instApply = Collections3.getFirst(
                custInsteadApplyService.selectByProperty("operOrg", UserUtils.getOperatorInfo().getOperOrg()));
        if (null != instApply) {
            return instApply.getBusinStatus();
        } else {
            return "";
        }
    }

    /**
     * 根据operOrg查询开户信息
     */
    public CustOpenAccountTmp findOpenAccoutnTmp() {
        final CustOpenAccountTmp accountInfo = Collections3
                .getFirst(this.selectByProperty("operOrg", UserUtils.getOperatorInfo().getOperOrg()));
        return accountInfo;
    }

    /**
     * 微信，删除附件
     */
    public int saveDeleteSingleFile(final Long anId) {
        final CustFileItem anFile = custFileItemService.selectByPrimaryKey(anId);
        BTAssert.notNull(anFile, "无法获取相应附件!");
        anFile.setBatchNo(-anFile.getBatchNo());
        return custFileItemService.updateByPrimaryKey(anFile);
    }

    /**
     * 微信查询开户成功后资料 --不能直接通过wechat标识去查询tmp表，因为若是微信绑定已开户账户，则tmp表中wechat标识为空--
     */
    public CustOpenAccountTmp findSuccessAccountInfo(final String anOpenId) {
        final CustWeChatInfo wehchatUserInfo = custWeChatService.findWechatUserByOpenId(anOpenId);
        BTAssert.isTrue(null != wehchatUserInfo.getCustNo(), "此微信账户未开户！");
        return Collections3.getFirst(this.selectByProperty("custNo", wehchatUserInfo.getCustNo()));
    }

    /**
     * 根据custNo查询已经开户的信息
     */
    public CustOpenAccountTmp findAccountInfoByCustNo(final Long anCustNo) {
        return Collections3.getFirst(this.selectByProperty("custNo", anCustNo));
    }

    /**
     * 根据custNo查询已经开户的信息
     */
    public CustInfo findCustInfoByCustNo(final Long anCustNo) {
        return custAccountService.findCustInfo(anCustNo);
    }

    /**
     * 平台查询客户信息
     */
    public Page<List<Map<String, Object>>> queryCustInfoByPlatform(final String anFlag, final int anPageNum,
            final int anPageSize) {
        /*if (!UserUtils.platformUser()) {
            throw new BytterTradeException("无相应权限操作！");
        }*/
        // 获取当前操作员id
        /*   final Long operId = UserUtils.getOperatorInfo().getId();
        // 获取当前操作员机构
        final String operOrg = UserUtils.getOperatorInfo().getOperOrg();
        final CustOperatorInfo custOper = new CustOperatorInfo();
        custOper.setId(operId);
        custOper.setOperOrg(operOrg);
        final CustOperatorInfo queryResult = this.custOperatorService.selectOne(custOper);
        if (!queryResult.getCustType().equals("0")) {
            throw new BytterTradeException("无相应权限操作！");
        }*/
        final List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
        final Page<CustInfo> custInfoList = custAccountService.selectPropertyByPage("GTEcustNo", "0L", anPageNum,
                anPageSize, "1".equals(anFlag));
        for (final CustInfo custInfo : custInfoList) {
            final Map<String, Object> tmpResultMap = new HashMap<String, Object>();
            tmpResultMap.put("custInfo", custInfo);
            final CustOpenAccountTmp tmpInfo = Collections3
                    .getFirst(this.selectByProperty("custNo", custInfo.getCustNo()));
            tmpResultMap.put("tmpInfo", tmpInfo);
            resultList.add(tmpResultMap);
        }
        return Page.listToPage(resultList, anPageNum, anPageSize, custInfoList.getPages(), custInfoList.getStartRow(),
                custInfoList.getTotal());
    }

    /**
     * @return
     */
    public List<SimpleDataEntity> queryCustInfoByPlatformSelect() {
        if (!UserUtils.platformUser()) {
            throw new BytterTradeException("无相应权限操作！");
        }

        final List<SimpleDataEntity> custInfos = custAccountService.queryValidCustInfo().stream()
                .map(custInfo -> new SimpleDataEntity(custInfo.getCustName(), custInfo.getId().toString()))
                .collect(Collectors.toList());

        return custInfos;
    }

    @Override
    public ICustAuditEntityFace findSaveDataByParentId(final Long anParentId) {

        return Collections3.getFirst(this.selectByProperty("parentId", anParentId));
    }

    public List<SimpleDataEntity> queryAllCustInfo() {

        final List<SimpleDataEntity> custInfos = custAccountService.queryValidCustInfo().stream()
                .map(custInfo -> new SimpleDataEntity(custInfo.getCustName(), custInfo.getId().toString()))
                .collect(Collectors.toList());

        return custInfos;
    }
}